1.首先,为了使元素可拖动,要先设置元素为可拖拽

  • 方法:添加draggable属性,设置为 true
  • 注意:链接和图像默认就支持拖拽,另外,如果一个元素中的文本被选中,那么这个元素和他的文本节点此时都支持被拖拽。
<body style="padding:30px;">
<div class="item">
<h3 draggable="true">我是被允许拖拽的h3元素</h3>
</div>
<div class="item">
<a href="http://www.baidu.com/">a链接</a>
</div>
<div class="item">
<img src="timg.jpg" alt="" width="200">
</div>
<div class="item">
<h3>选中文字后可被拖拽</h3>
</div>
</body>
<script>
document.ondragstart = function(){
console.log('dragstart')
}
</script>

2.拖拽事件监听

  • 拖拽事件一律使用(推荐)document监听,拖拽事件分2种,一种针对的是被拖拽的元素,第二种针对被拖拽的元素经过的容器
事件名称 事件对象(e.target) 说明
ondrag 被拖拽的元素 元素被拖拽期间(持续)触发
ondragstart 被拖拽的元素 开始拖拽元素时触发(推荐使用它记录被拖拽的元素)
ondragend 被拖拽的元素 元素拖拽结束时触发
ondragenter 接收容器 被拖拽的元素进入当前容器范围内时触发此事件
ondragover 接收容器 被拖拽的元素停留在当前容器范围内(持续)触发此事件
ondragleave 接收容器 被拖拽的元素离开当前容器范围内时触发此事件
ondrop 接收容器 释放鼠标键时触发此事件(触发时间早于ondragend)
  • 注意:浏览器默认阻止ondrop事件,需要在ondragover事件中阻止默认事件它才能被触发

3.完整的拖拽实例

  • 哪个元素被拖拽:可以在ondragstart事件中获取被拖拽的元素,并保存,问题1解决
  • 哪个容器负责接收:实际操作中,拖拽结束时经过的容器就是接收的容器,而能在此时获得接收容器的事件只能是drop事件(而drop事件默认被屏蔽,所以需要在ondragover事件中释放此事件)
<script>
// 设置全局变量记录被拖拽的元素
var dragNode = null
// 监听拖拽开始,记录被拖拽的元素
document.ondragstart = function (e) {
//记录被拖拽的元素
dragNode = e.target
// 修改通明度
dragNode.style.opacity = 0.5
}
// 监听拖拽结束
document.ondragend = function (e) {
// 恢复透明度
e.target.style.opacity = 1
// 清空dragNode
dragNode = null
}
// 阻止默认事件
document.ondragover = function (e) {
//允许被拖拉的节点放入目标节点
e.preventDefault()
}
// 监听拖拽释放,获取当前容器
document.ondrop = function (e) {
// 获取释放时的容器
var targetBox = e.target
// 判断是否是目标容器
if(targetBox.matches(".box")){
// 将元素移动到新的容器中
targetBox.appendChild(dragNode)
}
}
</script>

4.优化

  • 存在的问题:前面的案例中我们使用了一个全局变量来存储被拖拽的元素,但是使用全局变量容器污染全局
  • 解决办法:在拖拽事件中,事件对象event有一个dataTransfer属性对象,用来保存和读取拖放相关的数据
方法 说明
e.dataTransfer.setData(key,data) 设置数据(只能传入数字或者字符串)
e.dataTransfer.getData(key) 取数据(数字或者字符串)
e.dataTransfer.clearData(key) 清空数据
  • 代码实现:使用e.dataTransfer记录被拖拽元素的id属性值,从而通过这个值获取获取到被拖拽的元素
<script>
// 监听拖拽开始,记录被拖拽的元素
document.ondragstart = function (e) {
//判断节点是元素节点且有id属性,没有则赋予一个id
if(!e.target.id && e.target.nodeType === 1){
// 如果没有id,则设置一个id
e.target.id = "dragTest"
}
//保存id信息
e.dataTransfer.setData("id",e.target.id)
// 修改通明度
e.target.style.opacity = 0.5
}
// 监听拖拽结束
document.ondragend = function (e) {
// 恢复透明度
e.target.style.opacity = 1
}
// 阻止默认事件
document.ondragover = function (e) {
//允许被拖拉的节点放入目标节点
e.preventDefault()
}
// 监听拖拽释放,获取当前容器
document.ondrop = function (e) {
// 获取释放时的容器
var targetBox = e.target
// 根据存储的数据获取被拖拽的元素
var id = e.dataTransfer.getData("id")
var dragNode = document.querySelector("#"+id)
// 判断是否是目标容器
if(targetBox.matches(".box")){
// 将元素移动到新的容器中
targetBox.appendChild(dragNode)
}
}
</script>

HTML5 拖拽接口的更多相关文章

  1. 从零开始学 Web 之 HTML5(四)拖拽接口,Web存储,自定义播放器

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  2. Html5拖拽复制

    拖拽是一种常见的特性,即抓取对象以后拖到另一个位置. 在 HTML5 中,拖拽是标准的一部分,任何元素都能够拖拽. Html5拖拽非常常见的一个功能,但是大部分拖拽的案例都是一个剪切的过程, 项目中需 ...

  3. html5拖拽

    html5拖拽一 <!DOCTYPE html> <html> <head lang="en"> <meta charset=" ...

  4. HTML5 拖拽复制功能的实现方法

    Internet Explorer 9FirefoxOpera 12ChromeSafari 5 v1.0代码部分 <!DOCTYPE html><html><head& ...

  5. 每天一个JavaScript实例-html5拖拽

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  6. HTML5拖拽功能中 dataTransfer对象详解

    有了HTML5,老板再也不用担心我们的上传了,再加上有拖拽上传是不是很酷.百度一下,有关HTML5拖拽上传的文章和实例不少,都缺不了一个至关重要的东东DataTransfer.但是详细介绍的不多,尤其 ...

  7. 基于html5拖拽api实现列表的拖拽排序

    基于html5拖拽api实现列表的拖拽排序 html代码: <ul ondrop="drop_handler(event);" ondragover="dragov ...

  8. html5 拖拽(drag)和f放置(drop)

    知识要点 HTML5 (drag&drop) API  (Event) 拖放数据(对象):DataTransfer 拖放内容:setData getData 拖放效果(动作):dropEffe ...

  9. html5拖拽事件 xhr2 实现文件上传 含进度条

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  10. html5拖拽总结

    拖拽(Drag 和 drop)是 HTML5 标准的组成部分.拖拽是一种常见的特性,即抓取对象以后拖到另一个位置. Internet Explorer 9.Firefox.Opera 12.Chrom ...

随机推荐

  1. RxJS 系列 – 大杂烩

    前言 RxJS 有太多方法了, 想看完整的可以去看 REFERENCE – API List, 这篇介绍一些非 operator 的常用方法. NEVER NEVER.subscribe({ comp ...

  2. SQL Server – Soft Delete

    前言 Soft Delete 中文叫 "逻辑删", "软删除". 对比的自然就是 Hard Delete. 这篇想聊一聊它的好与坏, 什么时候可以考虑用它. H ...

  3. 数据库周刊33丨腾讯Tbase新版本发布;“2020数据技术嘉年华”有奖话题遴选;阿里云技术面试题;APEX 实现数据库自动巡检;MYSQL OCP题库……

    摘要:墨天轮数据库周刊第33期发布啦,每周1次推送本周数据库相关热门资讯.精选文章.干货文档. 热门资讯 1.中国移动国产OLTP数据库中标公告:南大金仓阿里,万里开源中兴 分获大单[摘要]近日,中国 ...

  4. 墨天轮沙龙 | Proxima 刘方:阿里巴巴大规模向量检索实时服务化引擎 Proxima SE

    导读 随着 AI 技术的广泛应用,以及数据规模的不断增长,向量检索也逐渐成了 AI 技术链路中不可或缺的一环. 在11月16日举办的[墨天轮数据库沙龙-向量数据库专场]邀请到阿里巴巴高级技术专家刘方, ...

  5. vue前端开发仿钉图系列(2)左侧图层列表的开发详解

    项目开发前还是特别说明一下组件库的重要性,谢谢饿了么团队分享的element组件库,大大节省了页面的开发成本.左侧图层列表核心功能有1.根据图层类型展示点线面2.开关控制右侧地图上点线面的展示和隐藏3 ...

  6. dotnet 冒泡排序

    // See https://aka.ms/new-console-template for more information using ConsoleApp1; Console.WriteLine ...

  7. 2. react项目【前端】+C#【后端】从0到1

    前端 1. 删除默认的src下所有文件,替换如下文件目录 2. src/index.js:

  8. 【ZROJ2730】简单题 可持久化分块题解

    Description 给定一棵 \(n\) 个节点的树,每次询问编号为 \([l, r]\) 的点中有多少个是祖先关系. \(n, q \le 10^5\). Solution 直接做的话树上的祖先 ...

  9. 9.24 csp(没学会的网络流)

    T1.商品 因为边界 l , r 是线性移动的,所以答案可以线性改变,直接用set维护连续段(小于l的和大于r的)的个数,并维护ans即可. 因为set的一个小错误调了两个小时,代码打成了一坨,结果最 ...

  10. 云原生周刊:CNCF 2023 年度调查报告 | 2024.4.15

    开源项目推荐 highlight 该项目是一个开源全栈监控平台.其功能包括错误监控.会话重放.日志记录.分布式跟踪等. Helm Compose Helm Compose 是一个 helm 插件,用于 ...