Skip to content
SORA's Blog
Go back

HTML5 Drag & Drop 踩坑记录

背景

在给拼图怪加画布内图片拖拽调换功能时,遇到了一个典型的”浏览器啥也不说就是不工作”的问题。

症状

根因

HTML5 Drag & Drop 规范有一条规则:

dragstart 设置 effectAlloweddragover 设置 dropEffect。浏览器在触发 drop 之前会检查两者是否兼容。不兼容就直接丢弃 drop,没有任何错误提示。

检查代码发现:

cell dragstart: effectAllowed = 'move'
wrap dragover:  dropEffect = 'copy'     ← 硬编码
cvs dragover:   dropEffect = 'copy'     ← 也是硬编码
→ 浏览器:'move' vs 'copy' 不兼容 → 拒绝 drop

修复

// 所有 dragover handler 改为动态匹配
e.dataTransfer.dropEffect = e.dataTransfer.effectAllowed === 'move' ? 'move' : 'copy';

次要问题

还有第二个坑:reorderPhotos() 直接调用 render() 替换 canvas.innerHTML,DOM 元素在拖拽过程中被替换了,浏览器的拖拽状态也被重置了。

修复方案:用 pendingReorder 标记,延迟到 dragend 才调 render()

教训

HTML5 Drag & Drop 的调试要点:

  1. drop 不触发 → 先查 effectAlloweddropEffect 是否兼容
  2. 事件冒泡链上最后的 dropEffect 是生效值
  3. DOM 替换在拖拽过程中会破坏浏览器拖拽状态
  4. 调试方法:dragenterdragoverdragleavedrop 四个事件都加 console.log

Share this post on:

Next Post
拼图怪 — 在线图片拼图工具