最简单的拖拉事件demo

169 阅读1分钟

前言

js实现拖拉效果的最简单demo,为实现原生拖拽效果提供思路。

1 拖拉效果展示

draggable.gif

2 代码实现

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .dropzone {
      width: 200px;
      height: 200px;
      border: 1px solid #f00;
    }

    #draggable {
      border: 1px solid #00f;
    }
  </style>
</head>
<body>
  <div class="dropzone">
    <div id="draggable" draggable="true">
      该节点可拖拉
    </div>
  </div>
  <div class="dropzone">
  </div>
  <div class="dropzone"></div>
  <div class="dropzone"></div>
  <script>

    let dragged

    // 用户开始拖拉时,在被拖拉的节点上触发
    document.addEventListener('dragstart', function(e) {
      dragged = e.target

      e.target.style.color = 'green'
    })
    
    // 拖拉结束时(释放鼠标键或按下 ESC 键)在被拖拉的节点上触发
    document.addEventListener('dragend', function(e) {
      e.target.style.color = '#000'
    })

    // 拖拉到当前节点上方时,在当前节点上持续触发(相隔几百毫秒),该事件的target属性是当前节点
    document.addEventListener('dragover', function(e) {
    // dragover 的默认行为是不允许 数据/元素 放置到其他元素中,所以要取消默认行为才能触发drop事件
      e.preventDefault()
    })

    // 拖拉进入当前节点时,在当前节点上触发一次,该事件的target属性是当前节点
    document.addEventListener('dragenter', function(e) {
      // 该事件会冒泡,为防止在其他节点上触发这个事件冒泡到document上被监听到,所以这里要过滤一下
      if (e.target.className === 'dropzone') {
        e.target.style.background = 'skyblue'
      }
    })

    // 拖拉操作离开当前节点范围时,在当前节点上触发,该事件的target属性是当前节点
    document.addEventListener('dragleave', function(e) {
      // 该事件会冒泡,为防止在其他节点上触发这个事件冒泡到document上被监听到,所以这里要过滤一下
      if (e.target.className === 'dropzone') {
        // 恢复目标节点(要离开的那个节点)背景色
        e.target.style.background = ''
      }
    })

    // 被拖拉的节点或选中的文本,释放到目标节点时,在目标节点上触发
    document.addEventListener('drop', function(e) {
      // 阻止事件默认行为(如:拖动链接在浏览器窗口松开会默认在新窗口打开链接)
      e.preventDefault()
      if (e.target.className === 'dropzone') {
        // 恢复目标节点(要释放的那个节点)背景色
        e.target.style.background = ''
        // 将被拖拉节点插入目标节点, 因为dragged是已经存在节点,所以会从原来位置移动到目标节点
        e.target.appendChild(dragged)
      }
    })

  </script>
</body>
</html>