拖拽效果


本文作者: jsweibo

本文链接: https://jsweibo.github.io/2020/02/04/%E6%8B%96%E6%8B%BD%E6%95%88%E6%9E%9C/

摘要

本文主要讲述了:

  1. DataTransfer.prototype.dropEffect
  2. DataTransfer.prototype.effectAllowed
  3. 设置拖拽图片

正文

DataTransfer.prototype.dropEffect

当进行拖拽时,DataTransfer.prototype.dropEffect用于配置鼠标悬浮在放置目标上方时的视觉效果

DataTransfer.prototype.dropEffect的取值范围:

  • copy 复制
  • move 移动
  • link 创建链接
  • none 禁止放置

注意:

  1. 由于该属性仅对于放置目标有效果,通常在dragover事件中设置
  2. 出于语义化考虑,如果DataTransfer.prototype.dropEffectmove,则开发者应该在drop事件中把源数据移除

示例:

learn_drag/index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<link rel="stylesheet" href="./css/index.css" />
<script defer src="./js/index.js"></script>
</head>
<body>
<div id="foo" draggable="true" class="draggable">
please drag it into the blue area
</div>
<div class="droppable"></div>
</body>
</html>

learn_drag/css/index.css

1
2
3
4
5
6
7
8
9
10
.draggable {
width: 100px;
height: 100px;
background-color: #f00;
}
.droppable {
width: 200px;
height: 200px;
background-color: #00f;
}

learn_drag/js/index.js

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
const draggableElement = document.querySelector('.draggable');
const droppableElement = document.querySelector('.droppable');

draggableElement.addEventListener('dragstart', function (event) {
console.log('dragstart');
event.dataTransfer.setData('text/plain', this.id);
});
draggableElement.addEventListener('dragend', function (event) {
console.log('dragend');
});
draggableElement.addEventListener('drag', function (event) {
console.log('drag');
});

droppableElement.addEventListener('dragenter', function (event) {
console.log('dragenter');
});
droppableElement.addEventListener('dragover', function (event) {
event.preventDefault();
console.log('dragover');
event.dataTransfer.dropEffect = 'move';
});
droppableElement.addEventListener('dragleave', function (event) {
console.log('dragleave');
});
droppableElement.addEventListener('drop', function (event) {
console.log('drop');
// 由于appendChild()会从源位置删除被添加的子元素,因此此处不再需要开发者手动删除
this.appendChild(
document.getElementById(event.dataTransfer.getData('text/plain'))
);
});

DataTransfer.prototype.effectAllowed

DataTransfer.prototype.effectAllowed用于配置被拖拽元素所允许的拖拽效果,若dragover中的DataTransfer.prototype.dropEffect与之不匹配,则无法触发drop事件

DataTransfer.prototype.effectAllowed的取值范围:

  • none 禁止放置
  • copy 复制
  • copyLink 复制或创建链接
  • copyMove 复制或移动
  • link 创建链接
  • linkMove 创建链接或移动
  • move 移动
  • all 复制或移动或创建链接
  • uninitialized 未初始化,等效于all

默认值为uninitialized

注意:该属性在且仅能在dragstart事件中配置

示例:

learn_drag/index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<link rel="stylesheet" href="./css/index.css" />
<script defer src="./js/index.js"></script>
</head>
<body>
<div id="foo" draggable="true" class="draggable">
please drag it into the blue area
</div>
<div class="droppable"></div>
</body>
</html>

learn_drag/css/index.css

1
2
3
4
5
6
7
8
9
10
.draggable {
width: 100px;
height: 100px;
background-color: #f00;
}
.droppable {
width: 200px;
height: 200px;
background-color: #00f;
}

learn_drag/js/index.js

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
const draggableElement = document.querySelector('.draggable');
const droppableElement = document.querySelector('.droppable');

draggableElement.addEventListener('dragstart', function (event) {
console.log('dragstart');
event.dataTransfer.effectAllowed = 'copy';
event.dataTransfer.setData('text/plain', this.id);
});
draggableElement.addEventListener('dragend', function (event) {
console.log('dragend');
});
draggableElement.addEventListener('drag', function (event) {
console.log('drag');
});

droppableElement.addEventListener('dragenter', function (event) {
console.log('dragenter');
});
droppableElement.addEventListener('dragover', function (event) {
event.preventDefault();
console.log('dragover');
event.dataTransfer.dropEffect = 'move';
});
droppableElement.addEventListener('dragleave', function (event) {
console.log('dragleave');
});
droppableElement.addEventListener('drop', function (event) {
console.log('drop');
});

设置拖拽图片

当拖拽发生时,默认情况下浏览器会根据被拖拽目标生成一个半透明的图片并使之伴随鼠标移动,但开发者也可以手动设置此图片。

注意:

  1. 在且仅能在dragstart事件的回调函数中设置
  2. 若此前未缓存过对应图片,则第一次拖拽时浏览器会去请求图片,第二次拖拽时图片才能生效

示例:

learn_drag/index.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<link rel="stylesheet" href="./css/index.css" />
<script defer src="./js/index.js"></script>
</head>
<body>
<h1>please select some text and drag it into the blue area</h1>
<a href="https://www.baidu.com/">please drag it into the blue area</a>
<img
src="https://www.baidu.com/img/bd_logo1.png"
alt="please drag it into the blue area"
/>
<div draggable="true" class="draggable">
please drag it into the blue area
</div>
<div class="droppable"></div>
<input type="text" placeholder="placeholder" />
<textarea placeholder="placeholder"></textarea>
</body>
</html>

learn_drag/css/index.css

1
2
3
4
5
6
7
8
9
10
.draggable {
width: 100px;
height: 100px;
background-color: #f00;
}
.droppable {
width: 200px;
height: 200px;
background-color: #00f;
}

learn_drag/js/index.js

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
const draggableElement = document.querySelector('.draggable');
const droppableElement = document.querySelector('.droppable');

draggableElement.addEventListener('dragstart', function (event) {
console.log('dragstart');

// 设置拖拽图片
let imageElement = new Image();
imageElement.src = 'https://www.baidu.com/img/bd_logo1.png';
event.dataTransfer.setDragImage(imageElement, 0, 0);
});
draggableElement.addEventListener('dragend', function (event) {
console.log('dragend');
});
draggableElement.addEventListener('drag', function (event) {
console.log('drag');
});

droppableElement.addEventListener('dragenter', function (event) {
console.log('dragenter');
});
droppableElement.addEventListener('dragover', function (event) {
event.preventDefault();
console.log('dragover');
});
droppableElement.addEventListener('dragleave', function (event) {
console.log('dragleave');
});
droppableElement.addEventListener('drop', function (event) {
console.log('drop');
});

参考资料

本文作者: jsweibo

本文链接: https://jsweibo.github.io/2020/02/04/%E6%8B%96%E6%8B%BD%E6%95%88%E6%9E%9C/


本文对你有帮助?请支持我


支付宝
微信