思路:

(1)首先通过拖拽物体,找到拖拽过程中进行变更的 dom 的属性值。

(2)获取到当前界面的总高度和总宽度。

(3)获取到需要进行拖拽的物体的高度和宽度,注意,拖拽物体的高度和宽度最好是具体数值而不是百分比,否则在处理四个角的时候会出现错误。

(4)获取物体拖拽是的运动坐标,上下(offsetTop)、左右(offsetLeft)。 注意,是拖拽物体的属性,不要找错对象

(5)通过测试得知 计算时以拖拽物体的 左边界 和 上边界 为准。

(6)判断物体移动到最右边:offsetLeft  > (当前界面的总宽度 - 物体的宽度)。

(7)判断物体移动到最左边:offsetLeft 为 0  。

(8)判断物体移动到最下边:offsetTop > (当前界面的总高度 - 物体的高度) 。

(9)判断物体移动到最上边:offsetTop 为 0  。

(10)拖拽过程中各种属性的获取方法是通过监听鼠标移动事件实现的。

具体操作如下:

1、新建文件

<el-dialog
    :visible.sync="dialogVisible"
    :closeOnClickModal="false"
    class="NewDialog"
    v-dialog-drag
    title="弹窗拖拽"
  >
  </el-dialog>

2、绑定鼠标(按下,松开)监听事件

//   进入界面时添加鼠标点击和松开的监听事件
  mounted() {
    window.addEventListener("mousedown", this.mouseDown);
    window.addEventListener("mouseup", this.mouseUp);
  },

3、编辑鼠标事件

// 鼠标监听事件
    // 鼠标长按的时候添加 鼠标移动监听事件
    mouseDown() {
      window.addEventListener("mousemove", this.mouseMove);
    },
    //鼠标松开的时候删除鼠标移动监听事件
    mouseUp() {
      window.removeEventListener("mousemove", this.mouseMove);
    },
    // 鼠标移动判断当前弹窗位置,限制住弹窗移动区域
    mouseMove() {
      // RelaHeight : 界面总高度 - 物体高度(以上边界为准)
      // RelaWidth : 界面总宽度 - 物体宽度(以左边界为准)
      // MoveTop : 物体上下移动的坐标变化
      // MoveLeft : 物体左右移动的坐标变化
      // DomSty : 需要修改的dom
      let RelaHeight =
          document.getElementById("app").offsetHeight -
          document.getElementsByClassName("el-dialog")[0].offsetHeight,
        RelaWidth =
          document.getElementById("app").offsetWidth -
          document.getElementsByClassName("el-dialog")[0].offsetWidth,
        MoveTop = document.getElementsByClassName("el-dialog")[0].offsetTop,
        MoveLeft = document.getElementsByClassName("el-dialog")[0].offsetLeft,
        DomSty = document.getElementsByClassName("el-dialog")[0].style;

      this.$VerdictDrag(RelaHeight, RelaWidth, MoveLeft, MoveTop, DomSty);
    },

 

4、新建  verdictDrag.js

src - > utils -> verdictDrag.js

 

if (ChangeSty.left) {
      if (Left > relaWidth) {
        ChangeSty.left = relaWidth + "px";
      }
      // 最左边
      if (Left < 0) {
        ChangeSty.left = 0;
      }
      // 最上边
      if (Top < 0) {
        ChangeSty.top = 0;
      }
      // 最下边
      if (Top > relaHeight) {
        ChangeSty.top = relaHeight + "px";
      }
      return ChangeSty;
    }

 

 

 

5、导入到 utils -> index.js

在 src -> utils 中新建 index.js文件,将 verdictDrag.js

element plus 跳转_监听事件

 

 

 然后在main.js 中将 utils注册一下,这里可以看这篇文章 定义全局方法,然后就全局可以使用 VerdictDrag()。

6、移除鼠标监听事件

// 离开界面的时候删除鼠标监听事件
  destroyed() {
    window.removeEventListener("mousedown", this.mouseDown);
    window.removeEventListener("mouseup", this.mouseUp);
  },

 7、注意事项

(1)在长按鼠标进行拖拽的时候会出现弹窗无移动,但是弹窗内容进行了位移同时鼠标指针样式变为 cursor: default 时的样式。这个时候松开鼠标mouseMove 方法未移除,需要重新点击之后才会移除。但是此问题目前只有在边界的时候才有几率出现,暂未解决。

(2)element 的弹窗组件貌似会自带 margin属性,为了计算方便,对此处样式进行了修改,如图:

首先是将弹窗自带的margin值调为0

element plus 跳转_监听事件_02

 

 

 这个时候弹窗会出现左上角,此处的操作是通过 flex 布局,将弹窗定位在页面中央:

element plus 跳转_拖拽_03

 

 

 这里对 margin 属性进行操作是因为如果不去掉,在计算数值的时候除了 界面总高/宽度、物体高/宽度外,还需要额外计算 margin 的值以及加上 margin 后导致的页面样式问题。为求计算方便,决定将 margin 设置为0。

ps:iview组件好像不需要这一步操作。

新手理解,若有误,请各位大佬指点,Thanks♪(・ω・)ノ