无需登录 数据私有 本地保存

HTML 拖放 API 演示 - 文件与元素拖拽交互

5
0
0
0

HTML5 拖放 API 交互演示

探索原生 Drag & Drop API 的强大能力 —— 文件上传、元素排序、自由拖拽、目标收集

文件上传: 0 标签收集: 0 排序操作: 0 自由拖拽: 0
文件拖放上传区
将文件拖放到此处
支持图片、文档、压缩包等任意文件 · 也可点击选择
可拖拽元素库

拖拽标签到右侧收集区(复制模式)

HTML CSS JavaScript Vue React Python Docker Git
目标收集区 0
将左侧标签拖放到此处
拖放排序列表 (拖拽行进行排序)
  • 1 学习 HTML5 Drag API 基础
  • 2 掌握 dragover 与 drop 事件
  • 3 实现文件拖放上传功能
  • 4 构建列表拖拽排序组件
  • 5 优化移动端触摸体验
自由拖拽区 (Pointer Events · 桌面&移动端均可用)
🟦
🟧
🟩
🟪
🟦

拖动彩色方块在区域内自由移动。此区域使用 Pointer Events 实现,兼容触摸屏。

拖放事件日志
--:--:--等待拖放事件...
常见问题与知识点

核心事件分为两类:
拖拽源事件:dragstart(开始拖拽)、drag(拖拽中持续触发)、dragend(拖拽结束)
放置目标事件:dragenter(进入目标)、dragover(在目标上方移动,需 preventDefault 才能允许 drop)、dragleave(离开目标)、drop(释放)

注意:dragover 默认每 50ms 触发一次,必须在其中调用 e.preventDefault() 才能触发 drop 事件。

HTML5 Drag API 在移动端浏览器(iOS Safari、Android Chrome)中支持不完整,主要表现为:
• 元素拖拽(draggable)在移动端几乎不触发
• 文件从系统拖放到浏览器在移动端不可用

解决方案:
• 元素拖拽:使用 pointerdown / pointermove / pointerup(Pointer Events API)替代,如本页的"自由拖拽区"
• 文件上传:提供点击按钮作为 fallback,移动端用户点击上传
• 也可使用 touchstart / touchmove / touchend 实现触摸拖拽

dataTransfer 是拖放操作中的数据载体,在 dragstart 时设置数据,在 drop 时读取。

主要方法:
setData(format, data) — 设置拖拽数据(如 'text/plain'、'text/html'、自定义MIME)
getData(format) — 读取拖拽数据
setDragImage(img, xOffset, yOffset) — 自定义拖拽幽灵图像
effectAllowed — 设置允许的操作('copy'、'move'、'link'、'all'等)
dropEffect — 在 dragover 中设置光标样式('copy'显示+号,'move'显示移动图标)

文件拖放上传使用 drop 事件中的 e.dataTransfer.files(FileList对象)获取文件。

关键步骤:
1. 在 dragover 中调用 e.preventDefault()
2. 在 drop 中获取 e.dataTransfer.files
3. 使用 FileReader 读取图片生成预览
4. 验证文件类型和大小
5. 通过 FormData 上传到服务器(或本地预览)

dragenter/dragleave 计数技巧:由于子元素会触发 dragleave,建议使用计数器跟踪进入/离开次数,避免闪烁。

核心思路:
1. 每个列表项设置 draggable="true"
2. dragstart 时记录被拖拽项的索引/ID,设置 opacity 样式
3. 在其他列表项的 dragover 中判断指针位置(上半部=插入上方,下半部=插入下方),添加视觉指示线
4. drop 时执行 DOM 插入操作(insertBefore)
5. dragend 时清除所有拖拽样式

判断插入位置:比较指针Y坐标与目标项中线的位置,rect.top + rect.height/2 为分界点。

使用 HTML5 Drag API:
• 需要在不同元素间传递数据(如排序列表、文件上传)
• 需要跨浏览器窗口/标签页拖放
• 需要与操作系统原生拖放集成(文件拖入浏览器)
• 桌面端为主

使用 Pointer Events:
• 元素在容器内自由移动
• 需要移动端触摸支持
• 需要更精细的动画控制
• 需要统一处理鼠标和触摸输入

实际项目中两者可结合使用,根据场景选择最合适的方案。