过去我们在web中想实现拖拽效果,基本上都是使用DOM事件模型中的mousedown、mousemove、mouseup的事件监听来模拟拖拽效果,为了实现实时的拖拽移动效果,还要不停地获取鼠标的坐标,还要不停的修改元素的位置,代码要堆很多,而且性能上也很不是很好,现在有了html5原生的Drag & Drop,小伙伴们再一次惊呆了,接着来看下html5拖放的具体使用方法,猛击 这里查看DEMO
事件描述:
dragstart:开始移动被拖拽元素时触发(主体是被拖拽元素)。
dragenter:被拖拽元素进入目标元素时触发(主体是目标元素)。
dragover:被拖拽元素在目标元素内移动时触发(主体是目标元素)。
dragleave:被拖拽元素离开目标元素时触发(主体是目标元素)。
drag:移动被拖拽元素时触发(主体是被拖拽元素)。
drop:目标元素完全接受被拖拽元素时触发(主体是目标元素)。
dragend:整个拖放操作结束时触发(主体是被拖拽元素)。
事件中的对象:
拖拽事件中,HTML5定义了dataTransfer对象,它包含了一些方法及属性。包括了setData()、getData()、clearData()方法来操作拖拽过程中传递的数据,setDragImage()方法来设置拖拽时鼠标的下面的图片(默认为被拖拽元素),effectAllowed 和 dropEffect 属性来设置拖放效果。
说明:
setData(format, data) 设置拖拽事件中传递的数据,format参数为数据类型
getData(format) 获拖拽事件中传递的数据,format参数为数据类型
clearData() 清除拖拽事件中传递的数据
setDragImage(element, x, y) 其中element表示拖拽时鼠标下面的图片,x 表示图标距离鼠标指针的x轴方向的偏移值,y表示图标距离鼠标指针y轴方向的偏移值。
effectAllowed属性设置被拖放元素拖放效果,dropEffect属性设置目标元素拖放效果。
注释: 以上属性的具体参数可以去w3.org去查看,这里就不一一列举。
注意:在整个拖拽过程中,一定要在dragover中执行preventDefault(),否则拖拽事件不会被触发,另外在拖拽的时候只会触发拖拽的相关事件,鼠标事件,例如mousemove,是不会触发的。
兼容性:(来自http://caniuse.com)
从上面的数据来看,除了手机端,和ie 8 9外,支持情况还是蛮好的, 但是几经周折测试后,发现该属性,碎片化严重,firefox下拖拽会新打开一个标签页来显示被拖拽元素的url,而safari有些版本直接就不支持,另外ie10中测试setDragImage直接是undefined,这是一些发现的问题,未发现的坑还不晓得有多少。
效果示例:
html代码:
<div class="box" id="left_box">
<div draggable="true" class="drag" id="drag1">A</div>
<div draggable="true" class="drag" id="drag2">B</div>
<div draggable="true" class="drag" id="drag3">C</div>
</div>
<div class="box" id="right_box"></div>
css代码:
* {
margin: 0;
padding: 0;
}
body {
width: 500px;
margin:20px auto;
}
.box {
width: 180px;
min-height: 320px;
padding: 0 10px 10px;
border: 2px dashed #ccc;
text-align: center;
}
#left_box {
float: left;
}
#right_box {
float: right;
}
.drag {
width: 180px;
height: 100px;
margin-top: 10px;
line-height: 100px;
color: #fff;
background: #428BCA;
text-align: center;
cursor: move;
}
javascript代码:
$(function(){ var dragElement = $('.drag') // 被拖拽元素 , targetElement = $('.box'); // 目标元素 dragElement.on('dragstart', function(e){ e.originalEvent.dataTransfer.setData("Text", e.target.id); // 设置拖拽事件中的传递数据 }) targetElement.on('dragover', function(e){ e.preventDefault(); // 阻止默认行为 }).on('dragenter', function(e){ e.target.style.borderColor = 'red'; // 进入目标元素,目标元素样式改变 }).on('dragleave', function(e){ e.target.style.borderColor = '#ccc'; // 离开目标元素,目标元素样式改变 }).on('drop', function(e){ // 把拖拽事件中的传递数据取出并插入到目标元素中 var data = e.originalEvent.dataTransfer.getData("Text"); $(this).append(document.getElementById(data)); // 目标元素样式改变 this.style.borderColor = '#ccc'; }) });
结束语:该属性固然很吸引人,但就目前阶段,碎片化严重,所以该属性目前来说,还是处于试玩阶段(神器chrome支持较好)。。。