Edge浏览器拖拽div元素致其他元素消失问题及求助
原生拖拽Edge兼容方案
问题背景
实现listbox中文本块(非选中文本)拖拽到其他区域的功能,Firefox中运行正常,但在新版Edge中存在以下异常:
- 开始拖拽时,除拖拽元素的直接祖先外,页面其余所有区域都会消失
- 打开JavaScript控制台时,问题要么不出现,要么延迟触发
推测为Edge底层渲染Bug,需纯原生JavaScript兼容方案,仅支持新版Edge与Firefox。
最小复现代码
<!DOCTYPE html> <html> <head> <title>Drag Issue</title> <style> body { margin: 0px; padding: 0px; overflow: hidden; background: gray; } div.area { box-sizing: border-box; position: absolute; overflow: hidden; display: block; } div.listbox { box-sizing: border-box; display: block; overflow: scroll; background: white; border: 1px solid black; padding: 3px; } div.item { display: block; background: white; font-family: Arial, Helvetica, sans-serif; } </style> </head> <body> <div class="area" style="left:0%;top:0%;width:65%;height:33%;background:red">TEXT</div> <div class="area" style="left:0%;top:33%;width:65%;height:33%;background:white">TEXT</div> <div class="area" style="left:0%;top:66%;width:65%;height:34%;background:blue">TEXT</div> <div class="area" style="left:65%;top:0%;width:35%;height:100%;background:green;padding:1em"> <div class="listbox" style="width:90%;height:80%;max-width:90%;max-height:80%"> <div class="item" draggable="true">abc</div> <div class="item" draggable="true">def</div> <div class="item" draggable="true">ghi</div> <div class="item" draggable="true">jkl</div> </div> </div> </body> </html>
兼容解决方案
通过手动控制拖拽预览元素并强制页面重绘,规避Edge的渲染异常:
修改后的完整代码
<!DOCTYPE html> <html> <head> <title>Drag Fix</title> <style> body { margin: 0px; padding: 0px; overflow: hidden; background: gray; } div.area { box-sizing: border-box; position: absolute; overflow: hidden; display: block; } div.listbox { box-sizing: border-box; display: block; overflow: scroll; background: white; border: 1px solid black; padding: 3px; } div.item { display: block; background: white; font-family: Arial, Helvetica, sans-serif; cursor: grab; } .drag-preview { position: fixed; top: -9999px; left: -9999px; background: white; border: 1px solid #ccc; padding: 3px; pointer-events: none; } </style> </head> <body> <div class="area" style="left:0%;top:0%;width:65%;height:33%;background:red">TEXT</div> <div class="area" style="left:0%;top:33%;width:65%;height:33%;background:white">TEXT</div> <div class="area" style="left:0%;top:66%;width:65%;height:34%;background:blue">TEXT</div> <div class="area" style="left:65%;top:0%;width:35%;height:100%;background:green;padding:1em"> <div class="listbox" style="width:90%;height:80%;max-width:90%;max-height:80%"> <div class="item" draggable="true">abc</div> <div class="item" draggable="true">def</div> <div class="item" draggable="true">ghi</div> <div class="item" draggable="true">jkl</div> </div> </div> <script> document.addEventListener('DOMContentLoaded', () => { const items = document.querySelectorAll('.item'); items.forEach(item => { item.addEventListener('dragstart', (e) => { // 创建拖拽预览替身 const preview = document.createElement('div'); preview.className = 'drag-preview'; preview.textContent = item.textContent; document.body.appendChild(preview); // 设置自定义拖拽图像,替代Edge默认渲染逻辑 e.dataTransfer.setDragImage(preview, 10, 10); // 强制页面重绘,修复元素消失问题 document.body.style.transform = 'translateZ(0)'; setTimeout(() => { document.body.style.transform = ''; }, 0); // 拖拽结束后清理临时元素 item.addEventListener('dragend', () => preview.remove(), { once: true }); }); }); }); </script> </body> </html>
方案说明
- 自定义拖拽预览:创建克隆元素并指定为拖拽图像,绕过Edge默认的拖拽渲染逻辑,避免触发Bug
- 强制重绘:利用
transform: translateZ(0)触发GPU加速重绘,解决拖拽时页面元素消失的问题 - 资源清理:在
dragend事件中一次性移除临时预览元素,避免内存泄漏
内容的提问来源于stack exchange,提问作者Carl Banks
相关产品推荐
相关产品推荐

