基于el-dialog的拖拽自定义指令

基于el-dialog的拖拽自定义指令

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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
import Vue from 'vue';
export default Vue.directive('dialogDrag', {
bind (el, binding, vnode, oldVnode) {
try {
// 弹框可拉伸最小宽高
let minWidth = 1000;
let minHeight = 635;
// 初始非全屏
let isFullScreen = false;
// 当前宽高
let nowWidth = 0;
let nowHight = 0;
// 当前顶部高度
let nowMarginTop = 0;
// 获取弹框头部(这部分可双击全屏)
const dialogHeaderEl = el.querySelector('.el-dialog__header');
// 获取弹框底部
const dialogFootEl = el.querySelector('.el-dialog__footer');
// 弹窗
const dragDom = el.querySelector('.el-dialog');
dragDom.style.maxHeight = '100VH';

let headFootHeight = 0
let timer = setInterval(() => {
if(dialogHeaderEl && dialogHeaderEl.offsetHeight){
headFootHeight = dialogHeaderEl.offsetHeight+dialogFootEl?.offsetHeight
clearInterval(timer)
}
}, 200);

// 给弹窗加上overflow auto;不然缩小时框内的标签可能超出dialog;
dragDom.style.overflow = 'auto';
// 清除选择头部文字效果
dialogHeaderEl.onselectstart = new Function('return false');
// 头部加上可拖动cursor
dialogHeaderEl.style.cursor = 'move';

// 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);

let moveDown = (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;
};
};
dialogHeaderEl.onmousedown = moveDown;
// 双击(头部)效果不想要可以注释
// dialogHeaderEl.ondblclick = (e) => {
// if (isFullScreen === false) {
// nowHight = dragDom.clientHeight;
// nowWidth = dragDom.clientWidth;
// nowMarginTop = dragDom.style.marginTop;
// dragDom.style.left = 0;
// dragDom.style.top = 0;
// dragDom.querySelector('.el-dialog__body').style.height = `calc(100VH - ${headFootHeight}px)`;
// dragDom.querySelector('.el-dialog__body').style.maxHeight = `calc(100VH - ${headFootHeight}px)`;
// dragDom.style.height = '100VH';
// dragDom.style.width = '100VW';
// dragDom.style.marginTop = 0;
// isFullScreen = true;
// dialogHeaderEl.style.cursor = 'initial';
// dialogHeaderEl.onmousedown = null;
// } else {
// dragDom.style.height = '635px';
// dragDom.querySelector('.el-dialog__body').style.height = '635px';
// dragDom.querySelector('.el-dialog__body').style.maxHeight = `635px`;
// dragDom.style.width = '1000px';
// dragDom.style.marginTop = nowMarginTop;
// isFullScreen = false;
// dialogHeaderEl.style.cursor = 'move';
// dialogHeaderEl.onmousedown = moveDown;
// }
// };

// 拉伸(右下方)效果不想要可以注释
// let resizeEl = document.createElement('div');
// dragDom.appendChild(resizeEl);
// // 在弹窗右下角加上一个10-10px的控制块
// resizeEl.style.cursor = 'se-resize';
// resizeEl.style.position = 'absolute';
// resizeEl.style.height = '10px';
// resizeEl.style.width = '10px';
// resizeEl.style.right = '0px';
// resizeEl.style.bottom = '0px';
// resizeEl.style.zIndex = '99';
// // 鼠标拉伸弹窗
// resizeEl.onmousedown = (e) => {
// // 记录初始x位置
// let clientX = e.clientX;
// // 鼠标按下,计算当前元素距离可视区的距离
// let disX = e.clientX - resizeEl.offsetLeft;
// let disY = e.clientY - resizeEl.offsetTop;

// document.onmousemove = function (e) {
// e.preventDefault(); // 移动时禁用默认事件

// // 通过事件委托,计算移动的距离
// let x = e.clientX - disX + (e.clientX - clientX);// 这里 由于elementUI的dialog控制居中的,所以水平拉伸效果是双倍
// let y = e.clientY - disY;
// // 比较是否小于最小宽高
// dragDom.style.width = x > minWidth ? `${x}px` : minWidth + 'px';
// dragDom.style.height = y > minHeight ? `${y}px` : minHeight + 'px';
// };
// // 拉伸结束
// document.onmouseup = function (e) {
// document.onmousemove = null;
// document.onmouseup = null;
// };
// };

// 拉伸(右边)效果不想要可以注释
// let resizeElR = document.createElement('div');
// dragDom.appendChild(resizeElR);
// // 在弹窗右下角加上一个10-10px的控制块
// resizeElR.style.cursor = 'w-resize';
// resizeElR.style.position = 'absolute';
// resizeElR.style.height = '100%';
// resizeElR.style.width = '10px';
// resizeElR.style.right = '0px';
// resizeElR.style.top = '0px';
// // 鼠标拉伸弹窗
// resizeElR.onmousedown = (e) => {
// let elW = dragDom.clientWidth;
// let EloffsetLeft = dragDom.offsetLeft;
// // 记录初始x位置
// let clientX = e.clientX;
// document.onmousemove = function (e) {
// e.preventDefault(); // 移动时禁用默认事件
// // 右侧鼠标拖拽位置
// if (clientX > EloffsetLeft + elW - 10 && clientX < EloffsetLeft + elW) {
// // 往左拖拽
// if (clientX > e.clientX) {
// if (dragDom.clientWidth >= minWidth) {
// dragDom.style.width = elW - (clientX - e.clientX) * 2 + 'px';
// }
// }
// // 往右拖拽
// if (clientX < e.clientX) {
// dragDom.style.width = elW + (e.clientX - clientX) * 2 + 'px';
// }
// }
// };
// // 拉伸结束
// document.onmouseup = function (e) {
// document.onmousemove = null;
// document.onmouseup = null;
// };
// };

// 拉伸(左边)效果不想要可以注释
// let resizeElL = document.createElement('div');
// dragDom.appendChild(resizeElL);
// // 在弹窗右下角加上一个10-10px的控制块
// resizeElL.style.cursor = 'w-resize';
// resizeElL.style.position = 'absolute';
// resizeElL.style.height = '100%';
// resizeElL.style.width = '10px';
// resizeElL.style.left = '0px';
// resizeElL.style.top = '0px';
// // 鼠标拉伸弹窗
// resizeElL.onmousedown = (e) => {
// let elW = dragDom.clientWidth;
// let EloffsetLeft = dragDom.offsetLeft;
// // 记录初始x位置
// let clientX = e.clientX;
// document.onmousemove = function (e) {
// e.preventDefault(); // 移动时禁用默认事件
// // 左侧鼠标拖拽位置
// if (clientX > EloffsetLeft && clientX < EloffsetLeft + 10) {
// // 往左拖拽
// if (clientX > e.clientX) {
// dragDom.style.width = elW + (clientX - e.clientX) * 2 + 'px';
// }
// // 往右拖拽
// if (clientX < e.clientX) {
// if (dragDom.clientWidth >= minWidth) {
// dragDom.style.width = elW - (e.clientX - clientX) * 2 + 'px';
// }
// }
// }
// };
// // 拉伸结束
// document.onmouseup = function (e) {
// document.onmousemove = null;
// document.onmouseup = null;
// };
// };

// 拉伸(下边)效果不想要可以注释
let resizeElB = document.createElement('div');
dragDom.appendChild(resizeElB);
// 在弹窗右下角加上一个10-10px的控制块
// resizeElB.style.cursor = 'n-resize';
// resizeElB.style.position = 'absolute';
// resizeElB.style.height = '10px';
// resizeElB.style.width = '100%';
// resizeElB.style.left = '0px';
// resizeElB.style.bottom = '0px';
// 鼠标拉伸弹窗
// resizeElB.onmousedown = (e) => {
// let EloffsetTop = dragDom.offsetTop;
// let ELscrollTop = el.scrollTop;
// let clientY = e.clientY;
// let elH = dragDom.clientHeight;
// document.onmousemove = function (e) {
// e.preventDefault(); // 移动时禁用默认事件
// // 底部鼠标拖拽位置
// if (ELscrollTop + clientY > EloffsetTop + elH - 20 && ELscrollTop + clientY < EloffsetTop + elH) {
// // 往上拖拽
// if (clientY > e.clientY) {
// if (dragDom.clientHeight >= minHeight) {
// dragDom.style.height = elH - (clientY - e.clientY) * 2 + 'px';
// dragDom.querySelector('.el-dialog__body').style.height = `calc(100% - ${headFootHeight}px)`;
// }
// }
// // 往下拖拽
// if (clientY < e.clientY) {
// dragDom.style.height = elH + (e.clientY - clientY) * 2 + 'px';
// dragDom.querySelector('.el-dialog__body').style.height = `calc(100% - ${headFootHeight}px)`
// }
// }
// };
// // 拉伸结束
// document.onmouseup = function (e) {
// document.onmousemove = null;
// document.onmouseup = null;
// };
// };
} catch (error) {
console.log(error);
}
}
});