如何在保留拖拽事件的同时消除元素拖拽时的幽灵图像
消除拖拽时的幽灵图像
浏览器原生拖拽机制会默认生成跟随鼠标的幽灵图像(拖拽预览),要保留自定义拖拽功能同时消除它,最可靠的方法是通过dataTransfer.setDragImage()方法替换默认预览为透明内容。
具体实现步骤:
- 在
dragstart事件回调中,创建一个1x1的透明Canvas元素(或直接使用一个隐藏的空元素) - 调用
event.dataTransfer.setDragImage()将这个透明元素设为拖拽预览图 - 注意:该方法需要传入的元素必须是DOM中已存在的(或者动态创建后临时加入DOM)
修改后的示例代码:
<body> <style> .dragContainer{ height: 200px; width: 500px; background: red; } .draggable{ display: flex; height: 100px; width: 100px; background: blue; } </style> <div class="dragContainer"> <a class="draggable" href=""></a> </div> <script> let initialOffset = 0; const draggableEl = document.querySelector(".draggable"); document.querySelector(".dragContainer").addEventListener("dragover", (event)=>{ event.preventDefault(); // 必须阻止默认,否则dragover事件不会持续触发 let offset = event.clientX - initialOffset; draggableEl.style.transform = `translateX(${offset}px)`; }); document.querySelector(".dragContainer").addEventListener("dragstart", (event)=>{ initialOffset = event.clientX; // 创建透明Canvas作为拖拽预览图 const canvas = document.createElement('canvas'); canvas.width = 1; canvas.height = 1; // 将Canvas加入DOM(部分浏览器要求元素必须在DOM中) document.body.appendChild(canvas); // 设置拖拽图像为透明Canvas event.dataTransfer.setDragImage(canvas, 0, 0); // 拖拽结束后移除临时Canvas setTimeout(() => document.body.removeChild(canvas), 0); }); </script> </body>
补充说明:
- 必须在
dragover事件中调用event.preventDefault(),否则浏览器会阻止自定义拖拽行为,导致元素无法持续移动 - 如果不想创建Canvas,也可以使用一个隐藏的空div(设置
opacity: 0或visibility: hidden),但Canvas方法更轻量化 - 针对Chrome中
<a>标签出现的文本幽灵,设置setDragImage后也会一并消除,因为替换了默认的预览内容
内容的提问来源于stack exchange,提问作者Lee Morgan
相关产品推荐
相关产品推荐

