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. vue3项目部署到Github

    此教程适应于以webpack,vue-cli,vite等脚手架构建的vue项目.当然,vue2和vue3都是可以滴. 1. 前提:你的代码库已经提交到Github上 如果没有的话,请到GitHub上新 ...

  2. CSS – Display block, inline, inline-block

    前言 之前 W3Schools 学习笔记就有提到了 CSS Layout - The display Property 这篇做更多的解释. 参考: CSS Display FLEX vs Block, ...

  3. mmap映射类型

    文件映射和匿名映射都是操作系统中对于内存映射的两种类型,主要应用于进程间的通信或者大量数据的处理. 文件映射,也就是内存映射文件,是把一个文件或者文件的一部分映射到进程的地址空间,它允许对文件进行随机 ...

  4. JDK线程池详解(全网最全-原理解析、源码详解)

    频繁创建新线程的缺点? 不受控风险 系统资源有限,每个人针对不同业务都可以手动创建线程,并且创建标准不一样(比如线程没有名字).当系统运行起来,所有线程都在疯狂抢占资源,毫无规则,不好管控. 另外,过 ...

  5. vagrant文件基础配置

    Vagrant.configure("2") do |config| config.vm.box = "centos7" # box 名称 config.vm. ...

  6. 在 KubeSphere 中部署高可用 Redis 集群

    作者:余生大大,大数据开发工程师,云原生爱好者,KubeSphere 社区用户. 前言 Redis 是在开发过程中经常用到的缓存中间件,在生产环境中为了考虑稳定性和高可用一般为集群模式的部署. 常规部 ...

  7. Windows电脑无法给airpods充电的解决办法

    耳机盒与电脑都有TYPEC接口,由于驱动问题,接在一起是充不了电的,需要更改设置解决: 打开设置 -> 蓝牙与其他设备 -> 显示更多设备 往下翻,找到"更多设备与打印机设置&q ...

  8. ROS入门21讲(5)

    九.服务数据的定义与使用 1.服务模型 2.自定义服务数据 Person.srv string name uint8 sex uint8 age uint8 unknown = 0 uint8 mal ...

  9. typescript 编译报错 不能用于索引类型

    Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 't ...

  10. awk优化钉钉通知测试报告

    一.背景 在之前的博客 Go服务自动触发单元测试覆盖率 中钉钉通知的效果实现如下图: 最近RD提出对本次和上次覆盖率的比对需求,并把比对结果也显示在钉钉通知上. 二.实现思路 要实现数据比对,就需要对 ...