拖放
拖动源元素会触发哪些事件?
- 顺序:
dragstart→drag→dragend; dragstart: 开始移动鼠标的瞬间触发;drag: 拖动过程中持续触发;dragend: 停止移动时触发;
放置目标会触发哪些事件?
- 顺序:
dragenter→dragover→drop或dragleave; dragenter: 拖动元素进入放置目标时触发;dragover: 只要仍在放置范围内就持续触发;dragleave: 离开放置范围时触发;drop: 放置到目标上时触发;
DataTransfer 如何传递数据?
- 来源: 拖放回调的
event.dataTransfer; - 作用: 由被拖动元素向放置目标传递字符串数据;
| 成员 | 作用 |
|---|---|
dropEffect | 放置效果: none/copy/link/move |
effectAllowed | 允许的拖动效果 |
files / items / types | 文件列表 / 数据项列表 / 类型列表 |
setData(format, data) | 写入指定格式的数据 |
getData(format) / clearData() | 读取 / 清除数据 |
setDragImage(image, x, y) | 自定义拖动图像 |
哪些元素默认可拖动, 如何自定义?
- 默认: 图片、链接和文本可以被拖动;
- 自定义: 用
draggable属性控制任意元素;
<img src="smile.gif" draggable="false" alt="Smiley face" />
<div draggable="true">...</div>
- 强制放置: 部分元素默认不接受放置, 在
dragover与dragenter中调用event.preventDefault()即可让任意元素成为放置目标;
droptarget.addEventListener("dragover", (event) => event.preventDefault());
droptarget.addEventListener("dragenter", (event) => event.preventDefault());
原生 DnD 有哪些能力边界?
- 长处: 能接住从操作系统拖进窗口的文件, JS 可读其内容;
- 短板: 无法禁止从某区域拖出, 无法限制只许水平/垂直拖动, 许多交互表达不了;
- 移动端: 对原生拖拽事件支持很弱;
- 取舍: 应用内自由拖动多用鼠标事件自实现; 需要 OS 文件、跨窗口等原生能力时才用 HTML5 DnD;