如何用javascript实现拖放功能【教程】
技术百科
夜晨
发布时间:2026-01-28
浏览: 次 原生拖放API中drop不触发的根本原因是浏览器默认阻止dragover事件,必须在dragover中调用event.preventDefault();dataTransfer仅支持字符串,推荐用ID查表还原数据;非draggable元素需手动设置draggable="true";移动端需touch事件模拟。
原生 JavaScript 的拖放(Drag and Drop)API 表面简单,实际容易卡在 dragover 事件被忽略、drop 不触发、或数据传不进目标元素上——根本原因不是写法错,而是浏览器默认阻止了这些事件的默认行为。
为什么 drop 事件完全不触发?
因为浏览器对 dragenter 和 dragover 默认不做任何事,更不会让 drop 发生。你必须显式调用 event.preventDefault(),而且得在 dragover(以及可选的 dragenter)里调用。
-
dragover是唯一必须阻止默认行为的事件;漏掉它,drop永远不会触发 -
dragenter阻止与否不影响drop,但能控制“进入目标区域”的视觉反馈(比如加 class) - 不能只在
drop里preventDefault()——太晚了,浏览器已经跳转或下载了
dataTransfer 只能传字符串?怎么传 DOM 元素或对象?
dataTransfer 的 setData() 方法只接受字符串类型值,但你可以用它传递标识符(如 ID 或索引),再在 drop 时查表还原真实数据。
- 不要尝试
setData('text/plain', JSON.stringify(obj))后在drop里JSON.parse()——跨域或安全策略可能拦截 - 推荐做法:拖拽开始前把源元素的引用缓存在全局 Map 或数组中,
setData('text/id', 'item-123'),drop时用该 ID 查找对应数据 - 如果只是移动 DOM 节点,直接
event.target.appendChild(draggedElement)更可靠,无需走dataTransfer
如何让非 draggable="true" 元素可拖?
只有设置了 draggable="true" 的元素(或表单控件、图片等原生可拖元素)才能触发拖拽起点。但你可以用 JS 主动触发:
立即学习“Java免费学习笔记(深入)”;
- 监听
mousedown,然后调用element.setPointerCapture()+element.draggable = true动态开启(注意后续要恢复) - 更稳妥的做法:在目标元素上加
draggable="true",再用 CSSuser-select: none
避免文字被误选
- 移动端不支持原生 drag API,必须用
touchstart/touchmove模拟——这点常被忽略,导致 H5 页面拖放失效
最易被绕过的细节是:拖放过程中若鼠标移出窗口(比如切到别的标签页),dragend 仍会触发,但 drop 已经没了;此时应靠 dragleave 或定时器兜底清理状态。
# ai
# 浏览器
# app
# css
# js
# json
# go
# javascript
# java
# class
# 字符串
# 为什么
# Event
# map
# select
# 标识符
# 跨域
# 字符串类型
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Win11怎么开启窗口对齐助手_Windows11
- 如何在Golang中实现微服务负载均衡_Golan
- 如何使用Golang实现容器安全扫描_Golang
- php中self::能调用子类重写的方法吗_静态绑
- Windows10电脑怎么设置文件权限_Win10
- Win11如何开启telnet服务 Win11启用
- php8.4如何调用com组件_php8.4win
- Win11怎么设置默认浏览器Chrome_Wind
- Go 中 := 短变量声明的类型推导机制详解
- 用Python构建微服务架构实践_FastAPI与
- 短链接还原php提示内存不足_调整PHP内存限制设
- Win11如何设置开机自动联网 Win11宽带连接
- Windows10电脑怎么设置防火墙出站规则_Wi
- Windows10电脑怎么连接蓝牙设备_Win10
- Win11鼠标灵敏度怎么调 Win11鼠标指针移动
- c++ reinterpret_cast怎么用 c
- 为什么Go建议使用error接口作为错误返回_Go
- Python项目维护经验_长期演进说明【指导】
- Windows10系统怎么查看CPU核心数_Win
- Win11键盘快捷键大全_Windows 11常用
- Win11怎么恢复误删照片_Win11数据恢复工具
- mac怎么分屏_MAC双屏显示与分屏操作技巧【指南
- 手机php怎么转mp4_手机端php文件转mp4a
- Win11怎么设置开机问候语_自定义Win11锁屏
- Mac的Time Machine怎么用_Mac系统
- Win11怎么设置默认输入法 Win11固定中文输
- 微信里的php文件怎么变mp4_微信接收php转m
- 如何优化Golang程序CPU性能_Golang
- Windows10如何重置此电脑_Windows1
- LINUX如何删除用户和用户组_Linux use
- Mac怎么给文件夹加密_Mac创建加密磁盘映像教程
- Win11怎么关闭系统声音_Win11系统提示音静
- 如何在Golang中处理云原生事件_使用Event
- Windows10系统服务优化指南_Win10禁用
- 如何在Golang中处理通道发送接收错误_防止阻塞
- Win10如何卸载自带Edge_Win10彻底卸载
- Mac电脑进水了怎么办_MacBook进水后紧急处
- Win11怎样安装钉钉客户端_Win11安装钉钉教
- c++中如何使用auto关键字_c++11类型推导
- Windows如何使用注册表查找和删除项?(reg
- php和redis连接超时怎么办_phpredis
- Mac如何将HEIC图片格式转为JPG_Mac批量
- 如何在 Python 中将 ISO 8601 时间
- php485返回空数组怎么回事_php485数据接
- Python文件管理规范_工程实践说明【指导】
- Win11此电脑不在桌面上_Windows 11桌
- Mac怎么设置登录项_Mac管理开机自启动程序【教
- c++如何使用std::bind绑定函数参数_c+
- Win11怎么查看已连接wifi密码 Win11查
- c# 在ASP.NET Core中管理和取消后台任


QQ客服