Q Code

遇事不决 可问春风 春风不语 遵循自心

H5中的Drag(拖拽)

H5中的Drag(拖拽)

近期项目需求中涉及到了Dom拖拽的需求,所以自己整理了一些学习笔记

Dom事件

应用于当前被拖拽元素的事件

  • ondrag 元素正在拖动时触发(整个过程持续触发)
  • ondragstart 用户开始拖动元素时触发
  • ondragend 用户完成元素拖动后触发
  • ondragleave 当鼠标离开拖拽元素时调用

应用于目标元素的事件

  • ondragenter 应用于目标元素,当拖拽元素进入时调用
  • ondragover 应用于目标元素,当停留在目标元素上时调用(持续触发)
  • ondrop 应用于目标元素,当在目标元素上松开鼠标时调用
  • ondragleave 应用于目标元素,当鼠标离开目标元素时调用

拖动元素

被拖动元素(除img,a标签,默认可以拖动)需要添加draggable="true"属性.

目标元素ondrop不生效?

ondrop事件始终不触发,原因是没有定义ondragover事件,ondragover事件是被拖拽元素在目标元素上拖拽过程中由目标元素触发,需要取消掉它的默认事件(e.preventDefault())才可以正确触发,ondrop事件是被拖拽元素在目标元素上面drop的时候由目标元素触发;

Demo Code

使用vue 简单写了一个小demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- html -->
<div class="box1">
<div v-for="(item, index) in list1" :key="index" draggable @dragstart="onDrag" :k="index">
<p>姓名:{{ item.name }}</p>
<p>电话:{{ item.phone }}</p>
</div>
</div>
<div class="box2" @dragover="ondragover" @drop="onDrop">
<template v-if="list2 && list2.length">
<div v-for="(item, index) in list2" :key="index">
<p>姓名:{{ item.name }}</p>
<p>电话:{{ item.phone }}</p>
</div>
</template>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// .javascript
data() {
return {
list1: [
{
name: '张三',
phone: 123456789123
},
{
name: '李四',
phone: 321987654321
},
{
name: "王五",
phone: "456789432122"
}
],
list2: []
}
},
methods: {
onDrag(e) {
const dataTransfer = e.dataTransfer;
const target = e.target;
const k = target.getAttribute("k");
dataTransfer.setData("k", k);
},
ondragover(e) {
e.preventDefault();
},
onDrop(e) {
const dataTransfer = e.dataTransfer;
const k = +dataTransfer.getData('k');
this.list1 = this.list1.filter((item, index) => {
if (index === k) {
this.list2.push(item);
}
else {
return item;
}
});
}
}

Demo效果图

image