在前端项目中,拖拽排序是一个常见的需求。本文将详细讲解如何实现拖拽排序。

实现步骤

  1. 首先,需要给每个可拖拽的元素添加一个 draggable 属性,值为 true,表示该元素可以被拖拽。
  2. 接着,需要监听每个可拖拽元素的 dragstart 事件,该事件在拖拽开始时触发。在该事件的回调函数中,需要设置拖拽数据,可以使用 event.dataTransfer.setData() 方法。
  3. 然后,需要监听每个可拖拽元素的 dragover 事件,该事件在拖拽元素经过目标元素时触发。在该事件的回调函数中,需要阻止默认行为,可以使用 event.preventDefault() 方法。
  4. 接着,在 dragover 事件的回调函数中,需要判断拖拽元素和目标元素的位置关系,可以使用 event.clientYelement.getBoundingClientRect() 方法。
  5. 然后,在 dragover 事件的回调函数中,需要根据位置关系,设置目标元素的样式,可以使用 element.classList.add()element.classList.remove() 方法。
  6. 最后,在 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');
  }
});
文章目录