拖拽交互
拖拽交互提供了直观的操作方式,让用户可以通过拖放来重新排序、移动或操作元素。
拖拽实现方式
原生API
HTML5 Drag and Drop API
鼠标事件
mousedown/mousemove/mouseup组合
触摸事件
touchstart/touchmove/touchend组合
第三方库
SortableJS、React DnD等
拖拽应用场景
| 场景 | 实现要点 | 用户体验 |
|---|---|---|
| 列表排序 | 拖拽重新排列列表项 | 直观的排序操作 |
| 文件上传 | 拖拽文件到指定区域 | 便捷的批量上传 |
| 组件布局 | 拖拽调整组件位置 | 个性化的界面定制 |
| 元素移动 | 拖拽移动元素到目标位置 | 直观的对象操作 |
拖拽实现方式
原生JavaScript
使用HTML5 Drag and Drop API或鼠标事件
// HTML:
<div id="draggable-list">
<div class="draggable-item" draggable="true" data-id="1">项目 1</div>
<div class="draggable-item" draggable="true" data-id="2">项目 2</div>
<div class="draggable-item" draggable="true" data-id="3">项目 3</div>
</div>
// JavaScript:
const draggables = document.querySelectorAll('.draggable-item');
const container = document.getElementById('draggable-list');
draggables.forEach(draggable => {
draggable.addEventListener('dragstart', dragStart);
draggable.addEventListener('dragend', dragEnd);
});
container.addEventListener('dragover', dragOver);
container.addEventListener('dragenter', dragEnter);
container.addEventListener('dragleave', dragLeave);
container.addEventListener('drop', dragDrop);
let draggedItem = null;
function dragStart() {
draggedItem = this;
setTimeout(() => this.classList.add('dragging'), 0);
}
function dragEnd() {
this.classList.remove('dragging');
}
function dragOver(e) {
e.preventDefault();
}
function dragEnter(e) {
e.preventDefault();
this.classList.add('drag-over');
}
function dragLeave() {
this.classList.remove('drag-over');
}
function dragDrop() {
this.classList.remove('drag-over');
if (draggedItem !== this) {
const allItems = Array.from(container.children);
const currentIndex = allItems.indexOf(this);
const draggedIndex = allItems.indexOf(draggedItem);
if (currentIndex > draggedIndex) {
container.insertBefore(draggedItem, this.nextElementSibling);
} else {
container.insertBefore(draggedItem, this);
}
}
}
Vue.js实现
使用Vue Draggable库或自定义指令
<!-- Vue模板 -->
<template>
<div>
<draggable
v-model="list"
@start="drag=true"
@end="drag=false"
item-key="id"
class="drag-area">
<template #item="{ element }">
<div class="draggable-item">
{{ element.name }}
</div>
</template>
</draggable>
</div>
</template>
<script>
import draggable from 'vuedraggable';
export default {
components: {
draggable
},
data() {
return {
drag: false,
list: [
{ id: 1, name: '项目 1' },
{ id: 2, name: '项目 2' },
{ id: 3, name: '项目 3' }
]
}
}
}
</script>
<style>
.drag-area {
min-height: 100px;
border: 2px dashed #ccc;
padding: 10px;
}
.draggable-item {
padding: 10px;
margin: 5px 0;
background: #f5f5f5;
border: 1px solid #ddd;
cursor: move;
}
.draggable-item.dragging {
opacity: 0.5;
}
</style>