Loading

从零实现一个原生js拖拽排序功能

源码如下:

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title></title>
    <style>
      #root {
        position: relative;
        width: 500px;
        margin: 100px auto;
        border: 1px solid red;
      }
      .item {
        width: 100%;
        position: absolute;
        left: 0;
        background-color: rgba(15, 128, 255, 0.4);
        border-bottom: 1px solid blue;
        cursor: pointer;
        display: flex;
        align-items: center;
        justify-content: center;
      }
    </style>
  </head>
  <body>
    <div id="root"></div>
    <script type="text/javascript">
      // 参数
      const data = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
      const height = 50

      // 初始化变量
      let children = []
      let target = null
      let moveTop = 0
      let targetNum = 0

      // 渲染元素
      const root = document.querySelector('#root')
      root.style.height = data.length * height + 'px'
      for (let i = 0, len = data.length; i < len; i++) {
        const item = data[i]
        const div = document.createElement('div')
        div.className = 'item'
        div.innerText = item
        div.style.top = i * height + 'px'
        div.style.height = height + 'px'
        drag(div)
        children.push(div)
        root.appendChild(div)
      }

      // 拖拽
      function drag(div) {
        div.onmousedown = function(e) {
          const top = e.clientY - div.offsetTop
          target = div
          targetNum = Math.round(div.offsetTop / height)
          document.onmousemove = function(e) {
            moveTop = e.clientY - top
            target.style.top = moveTop + 'px'
            move()
          }
        }
      }

      // 鼠标松开设置最终落下位置
      document.onmouseup = function() {
        document.onmousemove = null
        if (!target) return null
        const nowNum = Math.round(moveTop / height)
        if (nowNum >= children.length - 1) {
          target.style.top = (children.length - 1) * height + 'px'
        } else if (nowNum <= 0) {
          target.style.top = '0px'
        } else {
          target.style.top = nowNum * height + 'px'
        }
      }

      // 交换位置
      function move() {
        const nowNum = Math.round(moveTop / height)
        for (let i = 0, len = children.length; i < len; i++) {
          const item = children[i]
          if (target === item) {
            continue
          }
          const itemNum = parseInt(item.style.top) / height
          if (itemNum === nowNum) {
            if (itemNum < targetNum) {
              item.style.top = parseInt(item.style.top) + height + 'px'
            } else if (itemNum > targetNum) {
              item.style.top = parseInt(item.style.top) - height + 'px'
            }
            targetNum = Math.round(moveTop / height)
            return null
          }
        }
      }
    </script>
  </body>
</html>
posted @ 2020-07-09 23:59  fsdffsdf  阅读(626)  评论(1编辑  收藏  举报