vue 限制在指定容器内可拖拽的div

在这里插入图片描述

<template>
  <div class="container" id="container">
    <div class="drag-box center" v-drag v-if="isShowDrag">
      <div>无法拖拽出容器的div浮窗</div>
    </div>
  </div>
</template>

<script>
export default {
     
  data() {
     
    return {
     
      isShowDrag: true,
    };
  },
  //自定义指令
  directives: {
     
    drag: {
     
      // 指令的定义
      bind: function (drag_dom) {
     
        drag_dom.onmousedown = (e) => {
     
          // 按下鼠标时,鼠标相对于被拖拽元素的坐标
          let disX = e.clientX - drag_dom.offsetLeft;
          let disY = e.clientY - drag_dom.offsetTop;

          // 获取容器dom
          let container_dom = document.getElementById("container");

          document.onmousemove = (e) => {
     
            // 用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
            let left = e.clientX - disX;
            let top = e.clientY - disY;

            // 在容器范围内移动时,被拖拽元素的最大left值
            let leftMax =
              container_dom.offsetLeft +
              (container_dom.clientWidth - drag_dom.clientWidth);

            // 在容器范围内移动时,被拖拽元素的最小left值
            let leftMin = container_dom.offsetLeft + 1; //此处+1为容器的边框1px

            if (left > leftMax) {
     
              drag_dom.style.left = leftMax + "px";
            } else if (left < leftMin) {
     
              drag_dom.style.left = leftMin + "px";
            } else {
     
              drag_dom.style.left = left + "px";
            }

            // 在容器范围内移动时,被拖拽元素的最大left值
            let topMax =
              container_dom.offsetTop +
              (container_dom.clientHeight - drag_dom.clientHeight);

            // 在容器范围内移动时,被拖拽元素的最小left值
            let topMin = container_dom.offsetTop + 1; //此处+1为容器的边框1px

            if (top > topMax) {
     
              drag_dom.style.top = topMax + "px";
            } else if (top < topMin) {
     
              drag_dom.style.top = leftMin + "px";
            } else {
     
              drag_dom.style.top = top + "px";
            }
          };

          document.onmouseup = () => {
     
            document.onmousemove = null;
            document.onmouseup = null;
          };
        };
      },
    },
  },
};
</script>

<style lang="scss" scoped>
.drag-box {
     
  position: absolute;
  top: 100px;
  left: 100px;
  width: 300px;
  height: 100px;
  background: #fff;
  border-radius: 5px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  padding: 10px;
  // 改变鼠标样式为移动图标
  cursor: move;
  // 禁止文字被选中
  user-select: none;
}

.container {
     
  border: 1px solid red;
  width: 600px;
  height: 300px;
  margin: 30px;
}

.center {
     
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>

相关推荐

  1. vue弹窗,div

    2023-12-06 18:48:03       44 阅读
  2. Vue3封装弹窗

    2023-12-06 18:48:03       50 阅读
  3. vue实现dialog封装

    2023-12-06 18:48:03       24 阅读
  4. Vue3中如何将一个div进行

    2023-12-06 18:48:03       39 阅读
  5. vue事件

    2023-12-06 18:48:03       58 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-06 18:48:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-06 18:48:03       101 阅读
  3. 在Django里面运行非项目文件

    2023-12-06 18:48:03       82 阅读
  4. Python语言-面向对象

    2023-12-06 18:48:03       91 阅读

热门阅读

  1. 【CTA认证】Android CTA资料及信息安全要求

    2023-12-06 18:48:03       74 阅读
  2. 运维工程师装逼完全指南

    2023-12-06 18:48:03       49 阅读
  3. 静态路由和动态路由的区别

    2023-12-06 18:48:03       67 阅读
  4. repo常用命令解析(持续更新)

    2023-12-06 18:48:03       51 阅读
  5. 流畅的Python (节选)

    2023-12-06 18:48:03       51 阅读
  6. 22.Oracle中的临时表空间

    2023-12-06 18:48:03       63 阅读
  7. oracle varchar2 和 nvarchar2的区别

    2023-12-06 18:48:03       50 阅读
  8. OpenCV中的一些图像方法记录

    2023-12-06 18:48:03       52 阅读
  9. 同步加载、异步加载、延迟加载、预加载的区别

    2023-12-06 18:48:03       64 阅读