wangrong
2021-11-24 130b72d6c5734f8acaac0214b6dfe5c8bfa319c3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
import Vue from "vue";
 
// 自定义元素实现弹框拖拽[重点]
Vue.directive("draw", {
  inserted: function (el, binding, vNode) {
    el.setAttribute("style", "position: fixed; z-index: 9999");
  },
 
  bind: function (el, bindding, vNode) {
    el.setAttribute("draggable", true);
 
    let left, top, width, height;
 
    el._dragstart = function (event) {
      event.stopPropagation();
 
      left = event.clientX - el.offsetLeft;
 
      top = event.clientY - el.offsetTop;
 
      width = el.offsetWidth;
 
      height = el.offsetHeight;
    };
 
    el._checkPosition = function () {
      // 防止被拖出边界
 
      const width = el.offsetWidth;
 
      const height = el.offsetHeight;
 
      let left = Math.min(el.offsetLeft, document.body.clientWidth - width);
 
      left = Math.max(0, left);
 
      let top = Math.min(el.offsetTop, document.body.clientHeight - height);
 
      top = Math.max(0, top);
 
      el.style.left = left + "px";
 
      el.style.top = top + "px";
 
      el.style.width = width + "px";
 
      el.style.height = height + "px";
    };
 
    el._dragEnd = function (event) {
      event.stopPropagation();
 
      left = event.clientX - left;
 
      top = event.clientY - top;
 
      el.style.left = left + "px";
 
      el.style.top = top + "px";
 
      el.style.width = width + "px";
 
      el.style.height = height + "px";
 
      el._checkPosition();
    };
 
    el._documentAllowDraop = function (event) {
      event.preventDefault();
    };
 
    document.body.addEventListener("dragover", el._documentAllowDraop);
 
    el.addEventListener("dragstart", el._dragstart);
 
    el.addEventListener("dragend", el._dragEnd);
 
    window.addEventListener("resize", el._checkPosition);
  },
 
  unbind: function (el, bindding, vNode) {
    document.body.removeEventListener("dragover", el._documentAllowDraop);
 
    el.removeEventListener("dragstart", el._dragstart);
 
    el.removeEventListener("dragend", el._dragEnd);
 
    window.removeEventListener("resize", el._checkPosition);
 
    delete el._documentAllowDraop;
 
    delete el._dragstart;
 
    delete el._dragEnd;
 
    delete el._checkPosition;
  },
});
 
// v-dialogDrag: 弹窗拖拽
 
Vue.directive("dialogDrag", {
  bind(el, binding, vnode, oldVnode) {
    const dialogHeaderEl = el.querySelector(".el-dialog__header");
 
    const dragDom = el.querySelector(".el-dialog");
 
    dialogHeaderEl.style.cursor = "move"; // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
 
    const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);
 
    dialogHeaderEl.onmousedown = (e) => {
      // 鼠标按下,计算当前元素距离可视区的距离
 
      const disX = e.clientX - dialogHeaderEl.offsetLeft;
 
      const disY = e.clientY - dialogHeaderEl.offsetTop; // 获取到的值带px 正则匹配替换
 
      let styL, styT; // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
 
      if (sty.left.includes("%")) {
        styL =
          +document.body.clientWidth * (+sty.left.replace(/\%/g, "") / 100);
 
        styT =
          +document.body.clientHeight * (+sty.top.replace(/\%/g, "") / 100);
      } else {
        styL = +sty.left.replace(/\px/g, "");
 
        styT = +sty.top.replace(/\px/g, "");
      }
 
      document.onmousemove = function (e) {
        // 通过事件委托,计算移动的距离
 
        const l = e.clientX - disX;
 
        const t = e.clientY - disY; // 移动当前元素
 
        dragDom.style.left = `${l + styL}px`;
 
        dragDom.style.top = `${t + styT}px`; // 将此时的位置传出去 // binding.value({x:e.pageX,y:e.pageY})
      };
 
      document.onmouseup = function (e) {
        document.onmousemove = null;
        document.onmouseup = null;
      };
    };
  },
});
 
// v-dialogDragWidth: 弹窗宽度拖大 拖小
 
Vue.directive("dialogDragWidth", {
  bind(el, binding, vnode, oldVnode) {
    const dragDom = binding.value.$el.querySelector(".el-dialog");
 
    el.onmousedown = (e) => {
      // 鼠标按下,计算当前元素距离可视区的距离
 
      const disX = e.clientX - el.offsetLeft;
 
      document.onmousemove = function (e) {
        e.preventDefault(); // 移动时禁用默认事件 // 通过事件委托,计算移动的距离
 
        const l = e.clientX - disX;
 
        dragDom.style.width = `${l}px`;
      };
 
      document.onmouseup = function (e) {
        document.onmousemove = null;
 
        document.onmouseup = null;
      };
    };
  },
});