拖拽元素携带原div背景色问题:如何设置拖拽时图片透明?
解决拖拽元素携带父容器背景色的问题
我实现了一个在div间拖拽移动元素的功能,但拖拽图片元素时,它会“携带”原div的背景色。请问需要修改哪个函数或做什么调整,才能让拖拽图片时变为透明?
原代码示例
JavaScript
var dragStart = function(e){ //e.target.style.backgroundColor = "blue"; -> debug } var dragEnd = function(e){ var areas = document.querySelectorAll(".area"); //console.log(areas) -> debug if (e.target.id != ''){ target = e.target } else{ target = e.target.parentNode for(let temp of [1,2,3,4]){ target = target.parentNode } } for(var area of areas){ if((e.clientX > area.getBoundingClientRect().x && e.clientX < area.getBoundingClientRect().x +area.clientWidth ) && (e.clientY > area.getBoundingClientRect().y && e.clientY < area.getBoundingClientRect().y +area.clientHeight)){ if(area.childElementCount == 0){ area.appendChild(document.getElementById(target.id)); } if(area.childElementCount == 1){ aux = area.firstElementChild; target.parentElement.appendChild(document.getElementById(aux.id)); area.appendChild(document.getElementById(target.id)); break; } } } //e.target.style.backgroundColor = "red"; -> debug } document.addEventListener("dragstart" , dragStart); document.addEventListener("dragend" , dragEnd);
HTML
<div id="square" class="col area" style="background-color: #ffdeba; padding: 0; width:90px; height:90px;"> <div id="piece" draggable=true style="background-image: url('https://www.pngall.com/wp-content/uploads/5/Black-Dog-PNG.png');background-size: 60%; background-position: center; background-repeat: no-repeat; width: 100%; height:100%"></div> </div> <div id="square" class="col area" style="background-color: red; padding: 0; width:90px; height:90px;"> </div>
解决方案
问题根源是默认拖拽行为会生成触发元素的视觉快照,如果事件冒泡到父容器(.area),快照就会包含父容器的背景色。只需修改dragStart函数,并在dragEnd中做恢复处理:
- 阻止事件冒泡:确保拖拽目标是
#piece元素,避免父容器被当作拖拽对象 - 设置拖拽透明度:拖拽开始时修改元素为半透明,结束后恢复
- 修复全局变量问题:原代码中
target、aux未声明,添加let避免全局污染
修改后的代码
JavaScript
var dragStart = function(e){ // 阻止事件冒泡,锁定拖拽目标为piece元素 e.stopPropagation(); // 获取正确的拖拽元素 const dragElement = e.target.id === 'piece' ? e.target : e.target.querySelector('#piece'); // 设置拖拽时的半透明效果 dragElement.style.opacity = '0.5'; // 明确拖拽行为类型 e.dataTransfer.effectAllowed = 'move'; } var dragEnd = function(e){ // 恢复元素原有透明度 const dragElement = document.getElementById('piece'); dragElement.style.opacity = '1'; var areas = document.querySelectorAll(".area"); let target; // 声明变量避免全局污染 if (e.target.id != ''){ target = e.target } else{ target = e.target.parentNode for(let temp of [1,2,3,4]){ target = target.parentNode } } for(var area of areas){ if((e.clientX > area.getBoundingClientRect().x && e.clientX < area.getBoundingClientRect().x +area.clientWidth ) && (e.clientY > area.getBoundingClientRect().y && e.clientY < area.getBoundingClientRect().y +area.clientHeight)){ if(area.childElementCount == 0){ area.appendChild(document.getElementById(target.id)); } if(area.childElementCount == 1){ let aux = area.firstElementChild; // 声明变量 target.parentElement.appendChild(document.getElementById(aux.id)); area.appendChild(document.getElementById(target.id)); break; } } } } document.addEventListener("dragstart" , dragStart); document.addEventListener("dragend" , dragEnd);
进阶选项:完全透明拖拽
如果需要拖拽时完全隐藏原元素,可改用dataTransfer.setDragImage传入空白画布:
var dragStart = function(e){ e.stopPropagation(); // 创建空白画布作为拖拽占位图像 const blankCanvas = document.createElement('canvas'); blankCanvas.width = 1; blankCanvas.height = 1; e.dataTransfer.setDragImage(blankCanvas, 0, 0); // 隐藏原元素 e.target.style.visibility = 'hidden'; } var dragEnd = function(e){ // 恢复原元素可见性 document.getElementById('piece').style.visibility = 'visible'; // ... 保留原有dragEnd逻辑 }
内容的提问来源于stack exchange,提问作者Rafael
相关产品推荐
相关产品推荐

