被拖拽的元素上需要设置属性:draggable="true"
,才能被拖拽
被拖拽的元素有三个事件,分别是:dragstart开始拖拽、drag正在拖拽、dragend拖拽结束(鼠标抬起)
验证一下这三个事件:
效果:
当鼠标点击被拖拽元素时,触发dragstart事件,输出’dragstart’;
拖拽过程中,触发drag事件,输出’drag’;
鼠标抬起,拖拽结束,触发dragend事件,输出’dragend’
目标元素可绑定的事件有:dragenter,dragover,dragleave,drop
验证一下前三个
dragenter事件以鼠标位置为准,当鼠标进入目标元素范围,触发dragenter;鼠标离开目标元素范围,触发dragleave,或者鼠标抬起,被拖拽元素完全离开目标元素范围
target.addEventListener(‘dragenter’,function(){
console.log(‘dragenter’);
})
target.addEventListener(‘dragover’,function(){
console.log(‘dragover’);
})
target.addEventListener(‘dragleave’,function(){
console.log(‘dragleave’);
})
鼠标点在被拖拽元素最左上角时,当鼠标移入target区域,dragenter才触发,鼠标未进入,被拖拽元素进入大半部分了,也还没有触发dragenter事件;
鼠标点在被拖拽元素右边部分时,当鼠标进入target区域,被拖拽元素仅有小部分进入target范围,就已经触发了dragenter事件;
鼠标离开target区域,触发dragleave事件,或者在target区域放开鼠标,触发dragleave事件
drop事件:
在上一个例子中可以看到,鼠标在target区域放开,自动触发的是dragleave事件,被拖拽元素回到原位置,没有保留在鼠标松开的位置,这时候需要解除dragover的默认行为(即dragleave),触发drop事件,允许放置文件
target.addEventListener(‘dragenter’,function(){
console.log(‘dragenter’);
})
target.addEventListener(‘dragover’,function(e){
e.preventDefault();//取消dragover的默认行为
console.log(‘dragover’);
})
target.addEventListener(‘dragleave’,function(){
console.log(‘dragleave’);
})
target.addEventListener(‘drop’,function(){
console.log(‘drop’);
})
可以看到,鼠标在target区域松开,触发的不再是dragleave事件,而是drop
然后我就可以操作dom元素,当把元素拖到trarget范围内并drop时,让这个元素留在target中
target.addEventListener(‘drop’,function(){
this.appendChild(drag);
//此处的this指target,是target绑定的事件,当事件触发,由target执行相应的处理函数
})
效果:
如果我有两个需要拖拽的元素,就需要判断是哪个元素被拖过来了,然后将这个元素append到target下
这时候,就需要使用dataTransfer对象了
**dataTransfer对象:
1.getData()向dataTransfer对象中存放数据
2.setData() 从dataTransfer对象中读取数据**
var drag = document.getElementsByClassName(‘drag’)[0],
drag2 = document.getElementsByClassName(‘drag2’)[0],
target = document.getElementsByClassName(‘target’)[0];
//被拖拽元素
drag.addEventListener(‘dragstart’,function(e){
var dt = e.dataTransfer;
dt.setData(‘className’,this.className);//这里的this指的是drag
})
drag2.addEventListener(‘dragstart’,function(e){
var dt = e.dataTransfer;
dt.setData(‘className’,this.className);
})
//目标元素
target.addEventListener(‘dragover’,function(e){
e.preventDefault();//取消dragover的默认行为
})
target.addEventListener(‘drop’,function(e){
var dt = e.dataTransfer;
var dataName = dt.getData(‘className’);
this.appendChild(document.getElementsByClassName(dataName)[0]);
})
效果:
拖放小demo:把元素拖到目标位置删除,效果如下:
思路:给要删除的每个元素绑定dragstart事件,把索引值传到dataTransfer对象中,drop获取到这个索引值,找到对应dom元素,删除
注意:使用for循环绑定监听时,会构成闭包,遍历的i值不会立即传到dataTransfer中,只是累加,当触发dragstart事件时,i都是5
body,
ul,
li {
margin: 0;
padding: 0;
list-style: none;
}
li {
width: 100px;
height: 50px;
background: #ccc;
text-align: center;
line-height: 50px;
margin: 10px 0;
}
.target {
width: 300px;
height: 300px;
background: black;
color: #fff;
font-size: 20px;
}
- item1
- item2
- item3
- item4
- item5
- 删除列表