使用与不使用setTimeout隐藏拖拽图片的差异及原理探究
拖拽场景中setTimeout(0)的作用解析
相关代码
JavaScript
let c = document.querySelector(".imge"); c.addEventListener("dragstart", () => { setTimeout(() => { c.classList.add("hide") }, 0) })
CSS
.hide { display: none; }
HTML
<img src="https://picsum.photos/200/300" draggable="true" class="imge" alt="" height="100px">
问题现象
直接在dragstart事件回调里给元素添加hide类,拖拽时看不到被拖拽的图像;用setTimeout(() => {}, 0)包裹隐藏操作后,原图片会隐藏,却能正常看到拖拽的图像。
原因说明
- 浏览器拖拽快照的生成时机:浏览器触发
dragstart事件后,会立刻创建当前元素的拖拽快照(也就是拖拽时跟着鼠标移动的预览图)。如果在dragstart回调里直接把元素设为display: none,这个操作会在快照生成前执行,导致浏览器抓不到元素的视觉状态,拖拽时就看不到图像。 - setTimeout(0)的本质:延迟设为0不是真的立刻执行,而是把隐藏元素的回调放到浏览器事件循环的下一个任务队列。当前
dragstart回调执行完毕后,浏览器先完成拖拽快照的创建,再执行setTimeout里的隐藏操作——这时候原元素隐藏已经不影响之前生成的快照了,所以拖拽时能看到图像,原元素也会消失。
内容的提问来源于stack exchange,提问作者Ujjawal
相关产品推荐
相关产品推荐

