type
status
date
slug
summary
tags
category
icon
password

最终效果

notion image

📝 主要代码

模板

逻辑

dragIndex 和 dropIndex 用于存储拖动开始和放置位置的索引。
dragstart 函数:
  • 当用户开始拖动一个元素时触发。
  • e.stopPropagation() 阻止事件冒泡:确保了拖动操作只在当前元素上处理,避免了事件冒泡带来的潜在问题。
  • 将拖动元素的索引存储在 dragIndex 中。
  • 使用 setTimeout 延迟添加 moveing 类,以便在拖动过程中给元素添加一些视觉效果。
 
dragover 函数:
  • 当拖动元素进入另一个元素的区域时触发。
  • e.preventDefault() 允许放置操作。
  • e.stopPropagation() 阻止事件冒泡。
  • 将目标位置的索引存储在 dropIndex 中。
  • 如果 dragIndex 和 dropIndex 不同,表示拖动元素进入了新的位置:
    • 获取拖动的元素 draggedItem
    • 从原位置删除拖动的元素。
    • 如果拖动的元素位于目标位置之前,调整 dropIndex
    • 在新位置插入拖动的元素。
    • 更新 dragIndex 为新的位置。
 
dragenter 函数:
  • 当拖动元素在目标元素上方移动时触发。
  • e.stopPropagation() 阻止事件冒泡。
 
dragend 函数:
  • 当拖动操作结束时触发。
  • e.stopPropagation() 阻止事件冒泡。
  • 移除拖动元素的 moveing 类。
  • 重置 dragIndex 和 dropIndex 为初始值 1
 

注意:

在这里我选择了dragover而不是dragenter的原因是我的拖拽场景比较复杂,需要实时更新UI。有关这两个方法的区别如下:
1. dragenter 事件
特性:
触发时机dragenter 事件在拖动元素第一次进入另一个可拖动目标时触发。这意味着每次拖动元素进入另一个元素的边界时都会触发一次。
典型用途:通常用于改变元素的外观以表示它是一个可放置的目标,或用于记录拖动进入的次数。
优点:
触发频率低:只在拖动元素进入另一个元素时触发,因此触发频率较低,适合用来处理需要在元素进入时进行的操作,如高亮显示目标元素。
简单直观:适合在元素进入时执行一次性操作,如改变样式或添加边框。
缺点:
不适合实时更新:由于只在元素首次进入时触发,如果用户在元素内移动时需要实时更新(如动态调整放置位置),dragenter 并不合适。
边界问题:对于需要精确控制的场景,例如在拖动到目标元素内部但需要精确控制放置位置的情况下,dragenter 可能显得不够灵活。
2. dragover 事件
特性:
触发时机dragover 事件在拖动元素悬停在一个有效的放置目标上方时持续触发。它会在拖动元素的整个过程中频繁触发。
典型用途:通常用于在拖动过程中持续更新状态,如显示放置位置的预览或动态调整放置目标。
优点:
实时更新:由于事件频繁触发,可以根据用户的拖动位置实时更新 UI 或内部状态。例如,用于显示用户当前的放置位置,或者在用户拖动时动态调整目标位置。
更精确的控制dragover 允许你在整个拖动过程中精确控制放置逻辑,更适合那些需要动态调整放置位置的应用场景。
缺点:
触发频率高dragover 事件会在拖动过程中频繁触发,如果不加以控制,可能导致性能问题,特别是在处理复杂的 DOM 操作时。
需要额外的条件判断:因为事件频繁触发,如果不进行条件判断,可能导致多余的操作或者逻辑重复执行。
 
3.为什么 dragover 更自然?
动态反馈dragover 事件提供了实时反馈的能力,可以让用户在拖动过程中看到动态变化的位置提示,这通常会让用户觉得操作更加直观和自然。
实时调整:在用户拖动过程中,dragover 可以不断更新放置的位置,使得用户可以精确地选择放置的点,而不是仅仅在进入时一次性确定位置。

总结归纳

这段代码通过监听拖动事件,实现了一个列表元素的拖放排序功能。用户可以通过拖动元素来改变它们在列表中的顺序,拖动过程中会有视觉效果提示,拖动结束后会重置相关状态。