Drag and Drop(html5的优良特性)
前言
HTML5 的拖拽(Drag and Drop)API 是一项在 Web 开发中非常有用的特性,它允许用户通过拖拽元素来实现数据的传输和操作。通过拖拽,可以实现更丰富的交互效果,提升用户体验。
拖拽 API 的详细事件流程
-
dragstart: 当拖动操作开始时触发。可以在这个事件中设置拖动数据,改变拖动元素的外观等。
-
drag: 拖动过程中持续触发。通常用于监控拖动位置和状态。
-
dragover: 拖动元素在目标元素上方时持续触发。需要调用
event.preventDefault()
以允许放置操作。 -
dragenter: 拖动元素进入目标元素时触发。可以用于高亮显示目标元素。
-
dragleave: 拖动元素离开目标元素时触发。用于移除高亮显示。
-
drop: 拖动元素在目标元素上释放时触发。用于处理放置逻辑,如移动数据。
-
dragend: 拖动操作结束时触发。可以在此恢复元素外观等。
实现原理
-
拖动开始:当用户开始拖动一个可拖动元素时,会触发
dragstart
事件,开发者可以在该事件中设置被拖动的数据。 -
拖动过程:在拖动过程中,会不断触发
dragover
、dragenter
和dragleave
事件,开发者可以在这些事件中实现拖放区域的样式变化或其他逻辑。 -
放置目标:当被拖动的元素被放置在拖放区域内时,会触发
drop
事件,开发者可以在该事件中处理拖放操作,如处理被拖动的数据。
代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Drag and Drop Example</title>
<style>
* {
box-sizing: border-box;
}
body {
background-color: #1a89c1;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
overflow: hidden;
margin: 0;
}
.empty {
height: 150px;
width: 150px;
margin: 10px;
border: 3px solid #000;
background: #faf9f9;
}
.fill {
width: 145px;
height: 145px;
cursor: pointer;
background-image: url("../music/assets/bg.jpg");
background-size: cover;
}
.hold {
border: 5px solid #ccc;
}
.hovered {
background: #333;
border-color: white;
border-style: dashed;
}
</style>
</head>
<body>
<div class="empty">
<div class="fill" draggable="true">
</div>
</div>
<div class="empty"></div>
<div class="empty"></div>
<div class="empty"></div>
<div class="empty"></div>
<script>
// 获取填充元素和空白区域的引用
const fill = document.querySelector('.fill');
const empties = document.querySelectorAll('.empty');
// 添加填充元素的拖拽事件监听器
fill.addEventListener('dragstart', dragStart);
fill.addEventListener('dragend', dragEnd);
// 添加空白区域的拖放事件监听器
for (let empty of empties) {
empty.addEventListener('dragover', dragOver);
empty.addEventListener('dragenter', dragEnter);
empty.addEventListener('dragleave', dragLeave);
empty.addEventListener('drop', dragDrop);
}
// 拖拽开始时触发的函数
function dragStart() {
console.log('dragstart');
// 添加 CSS 类来标识当前元素正在被拖拽
this.classList.add('hold');
}
// 拖拽结束时触发的函数
function dragEnd() {
console.log('dragend');
// 移除 CSS 类
this.classList.remove('hold');
}
// 在空白区域上拖拽时触发的函数
function dragOver(e) {
// 阻止默认行为,以允许元素在此处被放置
e.preventDefault();
console.log('dragover');
}
// 拖拽进入空白区域时触发的函数
function dragEnter(e) {
e.preventDefault();
// 添加 CSS 类以表示拖拽元素进入了空白区域
this.classList.add('hovered');
console.log('dragenter');
}
// 拖拽离开空白区域时触发的函数
function dragLeave() {
// 移除 CSS 类
this.classList.remove('hovered');
console.log('dragleave');
}
// 在空白区域上释放拖拽元素时触发的函数
function dragDrop() {
// 清除之前可能存在的类名,以便放置新的元素
this.className = 'empty';
// 将填充元素放置到空白区域中
this.append(fill);
console.log('dragdrop');
}
</script>
</body>
</html>
实现效果:
拖拽 API 的高级用法
1. 设置拖动数据
在 dragstart
事件中,可以使用 event.dataTransfer
来设置拖动的数据。
function dragStart(event) {
event.dataTransfer.setData('text/plain', 'This text may be dragged');
}
2. 自定义拖动图像
可以使用 event.dataTransfer.setDragImage
来自定义拖动过程中显示的图像。
function dragStart(event) {
const img = new Image();
img.src = 'path/to/image.png';
event.dataTransfer.setDragImage(img, 10, 10);
}
3. 拖动多个元素
通过设置一个容器中的多个元素的 draggable
属性为 true
,并为每个元素添加 dragstart
事件监听器,可以实现同时拖动多个元素。在 dragStartMultiple
函数中,将多个被选中元素的 HTML 内容拼接成一个字符串,并将其设置为拖动数据。
const selectedItems = document.querySelectorAll('.selected');
selectedItems.forEach(item => {
item.draggable = true;
item.addEventListener('dragstart', dragStartMultiple);
});
function dragStartMultiple(event) {
const draggedItems = Array.from(selectedItems).map(item => item.outerHTML).join('');
event.dataTransfer.setData('text/html', draggedItems);
}
4. 拖动文件
使用 dragover
和 drop
事件可以处理文件的拖放操作。在这个例子中,通过阻止默认行为并添加和移除类名来改变拖放区域的样式,同时处理 drop
事件来获取拖放的文件并进行相应的处理。
const dropZone = document.querySelector('.drop-zone');
dropZone.addEventListener('dragover', event => {
event.preventDefault();
dropZone.classList.add('drag-over');
});
dropZone.addEventListener('dragleave', () => {
dropZone.classList.remove('drag-over');
});
dropZone.addEventListener('drop', event => {
event.preventDefault();
const files = event.dataTransfer.files;
handleFiles(files);
});
最后
学会拖拽的小伙伴,麻烦点个赞吧!
转载自:https://juejin.cn/post/7376491813169578021