dropzone属性已废弃,现代浏览器完全不支持;必须手动监听dragover(需同步调用preventdefault)和drop事件,并配合tabindex、aria属性实现可访问拖拽。

dropzone属性在现代浏览器中基本不可用
HTML dropzone 属性(如 dropzone="copy text/plain")早在 2016 年就被 Chrome 移除,Firefox 从未实现,Safari 仅在极早期实验性支持后迅速弃用。它不是可落地的跨端方案,所有依赖它的代码在当前主流浏览器(Chrome 120+、Firefox 125+、Safari 17+)中都**完全失效**。
替代方案必须手动绑定 dragover + preventDefault()
真正起作用的只有 JavaScript 事件监听。关键不是“加属性”,而是确保每个目标容器都显式处理 dragover:
-
dragover监听器必须存在,且函数体内**同步调用**event.preventDefault()—— 放在setTimeout或异步 Promise 里无效 - 如果目标是空
<div>,记得加 <code>min-height: 20px或padding: 8px,否则视觉上“拖不进去” - 不要只绑
drop,不绑dragover的drop永远不会触发 - 检测
'ontouchstart' in window,如果是移动端,直接切换到PointerEvent+ 手动坐标追踪(setPointerCapture+mousemove模拟) - 或引入轻量库如
interact.js,它内部已做 touch/mouse/pen 的统一抽象,避免重复踩坑 - 若使用
mode: "open"的 Shadow DOM,可用event.target.getRootNode().host拿到宿主元素,再判断是否带drop-zone类 - 更稳妥的做法:在创建 Shadow Root 时,把 drop 区域 DOM 节点直接暴露为组件实例属性(如
this.dropTarget = shadowRoot.querySelector('[data-drop-target]')),后续事件中直接引用,不依赖遍历
移动端必须放弃原生 Drag and Drop API
iOS Safari 和 Android Chrome 均不支持对自定义元素的原生拖放(draggable="true" 在 touch 环境下被忽略)。你看到的“能拖”,大概率是浏览器从地址栏拖链接或图片的特例,不能复用于业务逻辑。
实操路径只有两条:
Shadow DOM 下 closest(".drop-zone") 失效怎么办
当 drop 区域在 Shadow Root 内时,event.target.closest(".drop-zone") 无法穿透 Shadow Boundary。此时不能靠 CSS 类查找,而要提前约定宿主结构:
实际中最容易被忽略的是:dragover 的 preventDefault() 必须由事件监听器本身执行,不能委托给父级再判断条件后调用——因为事件捕获阶段无法取消默认行为,只有在目标阶段同步执行才有效。











