HTML5 drag/drop基本知识
利用H5原生接口实现一个拖拽效果,通常要经过以下几个步骤:
为需要的拖拽的目标元素设置属性draggable=true
监听被拖拽元素的dragstart事件
可以给拖拽操作设置拖拽时的图标
给被拖拽元素设置一个拖放目标
监听drop事件执行相关的操作
拖拽元素触发的事件顺序(ps: 先声明被拖拽的元素为A, 存放拖拽元素的容器为B):
dragstart事件: 首先当鼠标开始拖拽A时触发该事件,dragstart作用在A上面
dragenter事件: 拖拽A进入到目标元素B中去时触发该事件,dragenter作用在B上面
dragover事件: 当拖拽着A在目标元素B里面滑动时触发该事件,dragover作用在B上面
drop事件: 当拖拽着A释放在目标元素B里面时,松开鼠标触发该事件,drop作用在B上面(该事件一定要执行e.preventDefault(),否则drop事件不会被触发)
dragend事件: 当拖拽着元素A,不管是否放在B里面,只要松开了鼠标触发该事件,dragend作用在A上面
dragleave事件: 当拖拽着元素A进入了目标元素B,但是没有释放在B里面而是离开了B时触发该事件,drop和dragleave两个只会触发一个,dragleave作用在B上面
dataTransfer对象
当进行拖拽时,所有拖拽事件都有一个dataTransfer属性,它包含拖拽数据
我们可以用setData方法来设置需要传递的数据,需要提供两个参数: 数据类型和数据值
e.dataTransfer.setData('text/plain', 'hello world');
e.dataTransfer.setData('text/html', '
hello world
');e.dataTransfer.setData('text/uri-list', 'http://www.mozilla.org');
可以使用clearData方法来一个移除数据,需要传入一个参数: 待移除的数据的类型 如果传入参数为空,绑定上面的所有数据将会被清除
clearData在chrome浏览器中在事件drop设置无法正常删除元素,而在Firefox可以正常使用
e.dataTransfer.clearData('text/plain'); // 移除指定类型的数据
e.dataTransfer.clearData(); // 将会移除所有数据,拖拽就不会发生
然后在鼠标释放被拖拽元素触发drop事件时,我们去获取传递过来的数据
e.dataTransfer.getData('text/plain');
e.dataTransfer.getData('text/html');
我们也可以设置拖动反馈图片,默认是当前元素加上一个透明度为0.5的图案
// 第一次参数可以是一张图片的URL,可以是页面中的那个DOM元素,也可以是js生成的canvas,
总之你想显示什么就可以显示什么
e.dataTransfer.setDragImage(image, xOffset, yOffset);
了解了以上基本的drag拖拽操作后,我们就可以编写一个简单的拖拽程序了
首先声明一个被拖拽对象和一个目标元素
被拖拽对象
然后监听拖拽时相关的对象
function $(id) {
return document.getElementById(id);
}
let oDragMe = $('dragMe');
let oDropBox = $('dropHere');
oDragMe.addEventListener('dragstart', function(e) {
e.dataTransfer.setData('text/plain', e.target.outerHTML);
}, false);
oDropBox.addEventListener('dragover', function(e) {
e.preventDefault();
}, false);
oDropBox.addEventListener('drop', function(e) {
e.preventDefault(); // 解决Firefox浏览器会跳转链接
e.stopPropagation(); // 解决firefo浏览器拖拽元素新开一个搜索页面
tmpData = e.dataTransfer.getData('text/plain');
e.currentTarget.innerHTML = tmpData;
}, false);
如何在浏览器上面实现一个本地图片预览
当我们将文件系统图片直接拖进指定的目标元素时,先触发dropover事件, 后触发的目标元素上面的drop事件,而dragstart, dragenter会直接省略掉,拖拽进行的文件会存放在e.dataTransfer.files对象上面, 我们只需要对加载进来的文件进行type匹配就可以了, 然后我们利用**FileReader()**对象来读取图片信息,将其显示到页面上籁
oDropBox.addEventListener('dragover', function(e) {
e.preventDefault();
}, false);
oDropBox.addEventListener('drop', function(e) {
e.preventDefault();
e.stopPropagation();
// 可以同时预览多张图片
[].forEach.call(e.dataTransfer.files, function(file) {
// 对加载进来的文件type类型进行匹配,只显示图片
if(file && (/^image\/\w+/g).test(file.type)) {
var reader = new FileReader();
reader.onload = function(e) {
var img = document.createElement('img');
img.src = e.target.result;
oDropBox.appendChild(img);
};
reader.readAsDataURL(file);
}
})
}, false);
参考资料