HTML5草案中增加了Drag&Drop的支持,原来以为会比较方便的实现拖拽,但事实上还是很不成熟。
先看下drag&drop的W3C草案。
传统意义上的drag&drop行为实际上是由三个鼠标事件构成的:
通常我们只需要dragStart,drag,drop这三个事件就够了,如果需要在进入drop的区域有视觉效果变化,那么最多增加dragEnter,dragLeave这两个事件就可以了。
而在这个草案中却多定义了dragover和dragend这两个几乎没有用的事件,而且必须要实现dragover这个事件,非常的不好用,可以参看The HTML5 drag and drop disasterCross Browser drag drop。
dragstart | 绑定在拖拽对象上,当开始拖拽时触发 |
drag | 绑定在拖拽对象上,在拖拽时触发 |
dragend | 绑定在拖拽对象上,在拖拽结束时触发 |
dragenter | 绑定在可以drop的对象上,当拖拽进到此处时触发,只在进入这个对象时触发一次。 |
drageleave | 绑定在可以drop的对象上,当拖拽离开此处时触发,只在离开这个对象时触发一次。 |
dragover | 绑定在可以drop的对象上,当拖拽在此处时触发,不管鼠标是否移动都会多次触发。 |
drop | 绑定在可以drop的对象上,在允许drop的时候触发 |
HTML5定义了dataTransfer对象来传递拖拽的数据,可以通过setData()和getData()来操作dataTransfer中携带的数据。
主要是指拖拽的时候鼠标样式。
dataTransfer.effectAllowed | 设置被拖拽对象允许的操作,这个值可以是copy,move,link,copyMove,copyLink,linkMove,all,none |
dataTransfer.dropEffect | 设置drop对象上允许的操作,可以是copy,move,link |
设置html dom上需要拖拽元素的dragable属性为true, 以及对应的CSS属性。
HTML:
<div class="dragElement" >dafdf</div>
<a href="#" class="dragElement" draggable="true">Cat</a>
<div class="dragElement" ></div>
<div class="dragElement" draggable="true">Bird</div>
<div class="dropElement"></div>
CSS:
.dragElement{
width:150px;
height:50px;
background:red;
float:left;
margin:5px;
}
.dropElement{
width:350px;
height:350px;
background:green;
float:right;
}
/**对于Safari,还必须要在CSS中对能拖拽的元素设置-khtml-user-drag: element*/
*[draggable = true] {
-khtml-user-drag: element;
}
在js绑定相关的事件处理函数,这里使用了JQuery的bind。
JS代码:
var dragElements = $('.dragElement');
dragElements.bind('dragstart',function(e){
e.originalEvent.dataTransfer.effectAllowed = 'move';
e.originalEvent.dataTransfer.setData('Text',this.innerHTML);
});
var dropBox = $('.dropElement');
dropBox.bind('dragover',function(e){
//设置drop可以接受的行为,能不能drop由这里的设置决定,drop事件中不处理dropEffect
e.originalEvent.dataTransfer.dropEffect = 'move';
// 必须阻止默认事件,否则无法触发drop事件
if (e.preventDefault)
e.preventDefault();
});
dropBox.bind('dragenter',function(e){
alert('dragenter');
});
dropBox.bind('dragleave',function(e){
alert('drag leave');
});
dropBox.bind('drop',function(e){
alert('drop the data:'+e.originalEvent.dataTransfer.getData('Text'));
return false;
});
测试的浏览器:Firefox3.6, IE7+, Safari4, Chrome4+
运行点这里
HTML5的drag drop有不少浏览器兼容性的问题:
1.有的浏览器拖拽时候有阴影,有的则没有,见下图
2.在IE上只能拖拽<a>,<img>这两个标签(必须存在href属性)以及选中的文字,并且不需要设置dragable=true也可以拖拽(当然这也是W3C草案中的标准)。chrome, FF, Safari则可以拖拽设置dragable=true的任意元素。
3.IE的dataTransfer不能随便设置数据名称,只能设成"Text"或"URL",而其他浏览器则没有这个限制。
4.Safari中需要用CSS指定能被拖拽的元素。
5.拖拽时候的鼠标样式不一致。