h5拖动和鼠标拖动 简易拖动

595 阅读1分钟

一、h5 drag 实现简易拖动

  • 被拖动的元素 dragstart开始 -> drag拖动中 -> dragend拖动结束
  • 目的地对象 dragenter被拖动元素进入目的对象 -> dragover目的对象内 -> dragleave离开目的元素
  • 到达目的地之后,释放元素事件drop 需要取消浏览器的默认行为
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      #range {
        position: relative;
        width: 600px;
        height: 400px;
        margin: 10px;
        background-color: rgb(133, 246, 250);
      }
      .box1,
      .box2 {
        height: 100px;
        width: 100px;
        cursor: move;
        margin-top: 30px;
      }
      .box1 {
        color: #fff;
        background-color: #504f4d;
      }
      .box2 {
        background-color: #ff9204;
      }
    </style>
  </head>
  <body>
    <div id="range">
      <!-- 为了使元素可拖动,把draggable属性设置为true。
        true: 可以拖动 false: 禁止拖动 auto: 跟随浏览器定义是否可以拖动 
        文本、图片和链接是默认可以拖放的
      -->
      <div class="box1" draggable="true" id="source">source box1</div>
      <div class="box2" draggable="true" id="target">target box2</div>
    </div>
    <script>
      const main = document.getElementById("range");
      const icon = document.querySelector(".icon");
      const source = document.getElementById("source");
      const target = document.getElementById("target");
      source.ondragstart = function (event) {
        var e = event || window.event;
        e.dataTransfer.setData("Text", e.target.id);
        // 在元素开始被拖动时候触发
        console.log("开始拖拽", e.target.id);
      };
      source.ondrag = function () {
        // 在元素被拖动时反复触发
        console.log("拖拽中");
      };
      source.ondragend = function () {
        // 在拖动操作完成时触发
        console.log("拖拽结束");
      };
      // 目标元素
      target.ondragenter = function () {
        // 当被拖动元素进入目的地元素所占据的屏幕空间时触发
        // dragenter和dragover事件的默认行为是拒绝接受任何被拖放的元素
        console.log("进入目标元素");
      };
      target.ondragover = function (event) {
        var event = event || window.event;
        // 当被拖动元素在目的地元素内时触发
        console.log("在目标元素中拖拽");
        event.preventDefault();
      };
      target.ondragleave = function () {
        // 当被拖动元素没有放下就离开目的地元素时触发
        console.log("拖放离开目标元素");
      };
      target.ondrop = function (event) {
        // 当元素在目的地放下时触发
        console.log("进行放置");
        var ev = event || window.event;
        ev.preventDefault();
        // 目标dom 放到 拖动dom 之前
        // 父节点.insertBefore(新的子节点,作为参考的子节点);
        var data = ev.dataTransfer.getData("Text");
        const sourceDom = document.getElementById(data);
        sourceDom.parentNode.insertBefore(ev.target, sourceDom);
      };
      target.ondragstart = function (event) {
        var e = event || window.event;
        e.dataTransfer.setData("Text", e.target.id);
        console.log("开始拖拽", e.target.id);
      };
      // 目标元素
      source.ondragenter = function () {
        console.log("进入目标元素");
      };
      source.ondragover = function (event) {
        var event = event || window.event;
        console.log("在目标元素中拖拽");
        event.preventDefault();
      };
      source.ondragleave = function () {
        console.log("拖放离开目标元素");
      };
      source.ondrop = function (event) {
        console.log("进行放置");
        var ev = event || window.event;
        ev.preventDefault();
        var data = ev.dataTransfer.getData("Text");
        console.log("进行放置:data: ", ev.target, data);
        const sourceDom = document.getElementById(data);
        sourceDom.parentNode.insertBefore(ev.target, sourceDom);
      };
    </script>
  </body>
</html>

二、mousedown、mousemove和mouseup  实现简易拖动

1、鼠标按下mousedown 记录当前坐标,拖拽状态move=true,得到 移动过程中不变的值deltaLeft = e.clientX - e.target.offsetLeft
2、鼠标移动onmousemove:计算left 和top 移动的距离,移动
3、鼠标抬起onmouseup: move=false

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      #range {
        position: relative;
        width: 600px;
        height: 400px;
        margin: 10px;
        background-color: rgb(133, 246, 250);
      }

      .icon {
        position: absolute;
        height: 100px;
        width: 100px;
        cursor: move;
        background-color: #ff9204;
        user-select: none;
      }
    </style>
  </head>
  <body>
    <div id="range">
      <div class="icon">100*100</div>
    </div>
    <script>
      const main = document.getElementById("range");
      const icon = document.querySelector(".icon");
      let move = false;
      let deltaLeft = 0,
        deltaTop = 0;
      // 拖动开始事件,要绑定在被移动元素上
      icon.addEventListener("mousedown", function (e) {
        /*
         * @des deltaLeft 即移动过程中不变的值
         * clientX:鼠标指针距离可视窗口左侧边缘的距离,
         * 随滚动条变化而变化,如果拖动滚动条让元素距离可视窗口左侧越近,值越小。
         * offsetLeft:元素相对其定位父级(offsetParent)的左偏移量。
         */
        deltaLeft = e.clientX - e.target.offsetLeft;
        deltaTop = e.clientY - e.target.offsetTop;
        move = true;
      });

      // 移动触发事件要放在,区域控制元素上
      main.addEventListener("mousemove", function (e) {
        if (move) {
          const cx = e.clientX;
          const cy = e.clientY;
          /** 相减即可得到相对于父元素移动的位置 */
          let dx = cx - deltaLeft;
          let dy = cy - deltaTop;
          /** 防止超出父元素范围 */
          if (dx < 0) dx = 0;
          if (dy < 0) dy = 0;
          if (dx > 500) dx = 500;
          if (dy > 300) dy = 300;
          icon.setAttribute("style", `left:${dx}px;top:${dy}px`);
        }
      });
      // 拖动结束触发要放在,区域控制元素上
      main.addEventListener("mouseup", function (e) {
        move = false;
        console.log("mouseup");
      });
    </script>
  </body>
</html>