前端项目中的拖拽排序实现
在前端项目中,拖拽排序是一个常见的需求。本文将详细讲解如何实现拖拽排序。
实现步骤
- 首先,需要给每个可拖拽的元素添加一个
draggable
属性,值为true
,表示该元素可以被拖拽。 - 接着,需要监听每个可拖拽元素的
dragstart
事件,该事件在拖拽开始时触发。在该事件的回调函数中,需要设置拖拽数据,可以使用event.dataTransfer.setData()
方法。 - 然后,需要监听每个可拖拽元素的
dragover
事件,该事件在拖拽元素经过目标元素时触发。在该事件的回调函数中,需要阻止默认行为,可以使用event.preventDefault()
方法。 - 接着,在
dragover
事件的回调函数中,需要判断拖拽元素和目标元素的位置关系,可以使用event.clientY
和element.getBoundingClientRect()
方法。 - 然后,在
dragover
事件的回调函数中,需要根据位置关系,设置目标元素的样式,可以使用element.classList.add()
和element.classList.remove()
方法。 - 最后,在
dragend
事件的回调函数中,需要根据位置关系,更新数据并重新渲染页面。
示例代码
HTML 代码:
<div class="container">
<div class="item" draggable="true">Item 1</div>
<div class="item" draggable="true">Item 2</div>
<div class="item" draggable="true">Item 3</div>
<div class="item" draggable="true">Item 4</div>
<div class="item" draggable="true">Item 5</div>
</div>
CSS 代码:
.container {
display: flex;
flex-wrap: wrap;
}
.item {
width: 100px;
height: 100px;
margin: 10px;
background-color: #ccc;
text-align: center;
line-height: 100px;
}
.item.drag-over {
border: 2px dashed #f00;
}
JavaScript 代码:
const container = document.querySelector('.container');
let dragItem = null;
container.addEventListener('dragstart', (event) => {
dragItem = event.target;
event.dataTransfer.setData('text/plain', dragItem.textContent);
});
container.addEventListener('dragover', (event) => {
event.preventDefault();
const targetItem = event.target;
if (targetItem.classList.contains('item')) {
const dragRect = dragItem.getBoundingClientRect();
const targetRect = targetItem.getBoundingClientRect();
const isAfter = event.clientY > (targetRect.top + targetRect.height / 2);
if (isAfter) {
targetItem.classList.add('drag-over');
} else {
targetItem.classList.remove('drag-over');
}
}
});
container.addEventListener('dragend', (event) => {
const targetItem = event.target;
if (targetItem.classList.contains('item')) {
const dragRect = dragItem.getBoundingClientRect();
const targetRect = targetItem.getBoundingClientRect();
const isAfter = event.clientY > (targetRect.top + targetRect.height / 2);
if (isAfter) {
container.insertBefore(dragItem, targetItem.nextElementSibling);
} else {
container.insertBefore(dragItem, targetItem);
}
targetItem.classList.remove('drag-over');
}
});
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。