js实现列表的拖拽排序(附代码)

首先需要了解一些拖放事件,简而言之:
只要拖动元素就会依次触发下面的事件

  • dragstart
  • drag
  • dragend

当元素被拖动到有效的放置目标上时会依次触发下面的事件

  • dragenter:元素被拖动到放置目标上触发
  • dragover:放置目标范围内移动时持续触发
  • dragleave:拖出放置目标范围触发 / drop:放到放置目标中触发

下面捋一下思路及一些前置条件

  1. 先设定可以拖动的元素。
    默认情况下,图像、链接和文本可以拖动,想让其他元素可以拖动需要为其设置draggable属性【html部分】
  2. 确定需要绑定的事件。
    因为需要元素拖动到有效的放置目标上(范围内)才触发,所以这里使用drop事件。在绑定drop事件前需要了解一件事:所有元素都支持放置目标事件(比如drop)但是这些元素默认是不允许放置的,如果想将其设置成有效的放置目标就要重写dragover事件的默认行为。【每一个li都可拖动,但不必为每个li绑定事件,只需要使用事件委托给ul绑定事件即可。】
  3. 拖拽排序即拖动A元素(被拖动元素)到B元素(放置目标)上,前者插入到后者的后面
    拖拽排序即拖动A元素(被拖动元素)到A元素(放置目标)上或者放置到目标范围外,位置不变
    即拿二者索引进行比较,然后根据结果处理元素

代码实现

  1. html代码
  • 绿
  1. js代码
<script>
	var ul = document.getElementsByTagName("ul")[0];
    // 把ul设置为有效的放置目标
    ul.ondragover = function (event) {
      event.preventDefault();
    };
    var draging; // 存放被拖动元素
    ul.ondragstart = function (event) {
      draging = event.target;
    }
    ul.ondrop = function (event) {
      var target = event.target; // 放置目标
      if (target.nodeName === "LI" && target !== draging) {       
        if (getIndex(draging) < getIndex(target)) {
          target.parentNode.insertBefore(draging, target.nextSibling);
        } else {
          target.parentNode.insertBefore(draging, target);
        }
      }
    };
    // 获取当前元素index
    function getIndex(el) {
      var index = 0;
      if (!el || !el.parentNode) {
        return -1;
      }
      while (el = el.previousElementSibling) {
        index++;
      }
      return index;
    }
</script>

* 只测试了Chrome / IE,动画效果后续可能会补充

你可能感兴趣的:(js实现列表的拖拽排序(附代码))