- HTML5 (drag&drop) API (Event)
- 拖放数据(对象):DataTransfer
- 拖放内容:setData getData
- 拖放效果(动作):dropEffect、effectAllowd
- 拖放图像:setDargImage
学习目标
- 掌握html5原声拖放(drag& drop)API 与 拖放事件
- 了解拖放流程
- 学会解决拖放种的兼容
前置要求
- 原生dom操作
-
原生事件
- 默认行为(阻止默认行为)
- 事件冒泡(阻止事件冒泡)
什么是Drag与Drop?
- Drag:拖拉 拖拽
- Drop:放置 放下
在一个web页面中,选中文本,图像、链接默认是可拖拽的
当一段文本、图像或者链接或链接被拖动的时候,文本内容·图像·链接URL被设定为拖动数据。
这个功能很早就用了,但是没有提供对应接口来让我们对着种行为进行控制,Drag与Drop是html5 新增的拖放接口,提供了一套可以在页面中拖放的功能,
通过该功能,用户可以通过鼠标来拖动(可拖动)元素,并可以通过释放鼠标来设置这些元素(可放置)元素上。
注意:默认情况下,除了选中文本、图像、链接、其它元素都是不可拖动的
拖放流程
一个完整的拖放流程包括两个大的方面:
- 拖拽(Drag)
- 放置(Drop)
拖拽
- 设置拖拽属性
- 监听处理拖拽事件
- 设置拖放数据
放置
- 设置(开启)元素放置特性
- 监听处理拖拽与放置事件
- 处理放置数据后续行为
流程
要实现拖放,我们的经过一系列的流程
设置拖放属性
draggable
- 一种枚举属性,设置某元素是否可以被拖拽,它可以有一下的值:
- true,这表明元素可能拖动
- false,这表明元素可能不会被拖动,默认
注意:
- 与selected 、checked 等属性不同 dragegable属性的值必须是true或false中的一个
- 选中文字、图像、链接的draggable属性值默认为:true
- firefox如果非默认可拖放元素,如果仅仅只是设置draggale为true,还不能使他们可以拖放,需要同时设置拖放内容
- event.dataTransfer.setData("text","")
- 兼容性:chrome/firefox/edge 对拖放的大部分特性都有不错的支持,ie10+才有一些支持
基本拖拽代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <p>拖拽基本流程</p> <div> <a href="http://baidu.com">baidu</a> </div> <!--图片地址自己更换本地图片 --> <img src="./images/logo-new.png" draggable="false" /> <!-- 设置被拖放元素的draggable属性为true --> <div id="box1" draggable="true" style="width: 100px;height: 100px;background: red"></div> <script> /* 我们可以给默认可以拖拽的元素(选中的文本、链接、图像)设置draggable为false,就可以阻止它们拖拽 firefox:如果拖拽的元素没有设置拖放内容,还是不能拖放 - draggable=true - 设置拖放内容 */ let box1 = document.querySelector(\'#box1\'); box1.ondragstart = function(e) { // 设置拖放内容:e.dataTransfer.setData(\'text\', \'kaikeba\'); e.dataTransfer.setData(\'text\', \'kaikeba\'); } </script> </body> </html>
拖放事件
拖放事件又分为:
- 基本拖拽元素事件
- 基本放置元素的事件
| 事件名称 | 描述 | 事件源 |
| dragestart | 当用户开始拖动一个元素或选中的文本时触发 | 被拖动元素 |
| drag | 当拖动元素或选中的文本时触发(每100毫秒触发一次) | 被拖动元素 |
| dgagend | 当拖拽操作结束时触发(比如松开鼠标按键或敲“esc”键) | 被拖动元素 |
| dragenter | 当拖动元素选中的文本到一个可释放目标时间触发 | 可放置元素 |
| dragover | 当元素或选中的文本被拖到一个可释放目标上时触发(每100毫秒触发一次) | 可放置元素 |
| draglave | 当拖动元素或选中的文本离开一个可释放目标触发 | 可放置元素 |
| drop | 当元素或选中的文本在可释放目标上被释放时触发 | 可放置元素 |
默认行为
一些动作(事件)会有一些默认行为,比如drag 比如默认情况下,图片是可以拖放的,自在释放的时候会新开窗口等,必要的时候,我们可以通过 preventDefault()来阻止默认是行为的发生。
常见一些默认行为(需要先了解下面的拖放数据-拖放内容)
不是所有元素都可以作为放置元素的,但是可以通过在放置元素的ondragover 中阻止默认行为来使其可以成为放置元素
- 在firefox的drop事件中,如果拖放的元素有设置具体非空拖放内容,则或触发浏览器默认行为:新开窗口(根据内容进行访问:非链接=》访问浏览器默认搜索引擎,连接=》访问连接地址)
- window:e.preventDefault()和e.stopPropageation()阻止默认行为和冒泡
- mac:e.preventDefault()阻止默认行为
拖拽事件代码示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>拖拽事件使用</title> </head> <body> <div id="box1" draggable="true" style="width: 100px;height: 100px;background: red"></div> <div id="box2" draggable="true" style="width: 200px;height: 200px;background: green; position: absolute; left: 400px;top: 200px;"></div> <img src="./images/logo-new.png" /> <script> let box1 = document.querySelector(\'#box1\'); let box2 = document.querySelector(\'#box2\'); box1.ondragstart = function(e) { // 如果在这里设置了拖拽的数据,则会触发浏览器的默认行为 e.dataTransfer.setData(\'text\', \'http://kaikeba.com\'); console.log(\'dragstart\'); } box1.ondrag = function() { console.log(\'drag\'); } box1.ondragend = function() { console.log(\'dragend\'); } box2.ondragenter = function() { console.log(\'dragenter\'); } box2.ondragleave = function() { console.log(\'dragleave\'); } /* 默认情况下,不是所有元素都能成为放置元素的 我们需要在dragover事件中阻止默认的行为:不允许放置 */ box2.ondragover = function(e) { // 该事件每次触发的时候都会重置默认行为 e.preventDefault(); console.log(\'dragover\'); } box2.ondrop = function(e) { // 当drop事件触发的时候,还有会有其它的一些默认的行为 e.preventDefault(); e.stopPropagation(); console.log(\'drop\'); } </script> </body> </html>
拖放数据
我们拖放过程中的效果和拖放产生的内容都成为拖放数据,要对拖放数据进行操作,首先我们得先了解一个对象, dataTransfer
DataTransfer
所有的拖放事件event对象有一个dataTransfer属性,我们可以通过它来设置和获取拖放过程中的数据。dataTransfer属性的一个DataTranfer类型对象。
拖放内容
DataTranfer.setData(type,data);
设置拖放内容