通过mousemove判断dialog哪条边缩放,配合mousedown开启移动、尺寸修改。
dialog.ts
// element-plus 的 dialog 的拖拽方法
const dialogDrag = (el: any, binding: any) => {
addEventFun();
function addEventFun() {
// 可视窗口的宽度
const clientWidth = document.documentElement.clientWidth
// 可视窗口的高度
const clientHeight = document.documentElement.clientHeight
// 弹窗的容器
const domDrag = el.parentElement.parentElement
// 拖拽的div
if (domDrag) {
// 获取元素
const dialogDom = domDrag;
const headerDom = dialogDom.getElementsByClassName('el-dialog__header')[0];
const dialogBoxDom = dialogDom.parentElement;
// 初始化变量
let startX, startY, initialX, initialY, newWidth, newHeight;
let isDrag = false;
let dragPosition = {
x: 0,
y: 0,
};
let isResizing : any = false;
let isMousedown = false;
headerDom.style.cursor = 'move';
dialogDom.style.position = 'absolute';
dialogDom.style.width = '60%';
dialogDom.style.height = '80%';
dialogDom.style.top = '10%';
dialogDom.style.left = '20%';
dialogDom.style.margin = '0';
// 鼠标移动改变指针样式
dialogDom.addEventListener('mousemove', (e: any) => {
if (isMousedown) return;
const size = 5;
const width = dialogDom.clientWidth;
const height = dialogDom.clientHeight;
const dialogBoxX = e.pageX - dialogBoxDom.offsetLeft;
const dialogBoxY = e.pageY - dialogBoxDom.offsetTop;
startX = dialogBoxX - dialogDom.offsetLeft;
startY = dialogBoxY - dialogDom.offsetTop;
// console.log(width, height);
if (startX < size && startY < size) {
dialogDom.style.cursor = 'nw-resize';
isResizing = 'top-left';
} else if (startX > width - size && startY > height - size) {
dialogDom.style.cursor = 'nw-resize';
isResizing = 'bottom-right';
} else if (startX > width - size && startY < size) {
dialogDom.style.cursor = 'ne-resize';
isResizing = 'top-right';
} else if (startX < size && startY > height - size) {
dialogDom.style.cursor = 'ne-resize';
isResizing = 'bottom-left';
} else if (startX < size) {
dialogDom.style.cursor = 'e-resize';
isResizing = 'left';
} else if (startX > width - size) {
dialogDom.style.cursor = 'e-resize';
isResizing = 'right';
} else if (startY < size) {
dialogDom.style.cursor = 'n-resize';
isResizing = 'top';
} else if (startY > height - size) {
dialogDom.style.cursor = 'n-resize';
isResizing = 'bottom';
} else {
dialogDom.style.cursor = 'default';
isResizing = false;
}
});
// 拖拽
headerDom.addEventListener('mousedown', (e: any) => {
isDrag = true;
dragPosition.x = e.pageX - dialogBoxDom.offsetLeft - dialogDom.offsetLeft;
dragPosition.y = e.pageY - dialogBoxDom.offsetTop - dialogDom.offsetTop;
});
// 鼠标按下判断是否开启尺寸拖拽
dialogDom.addEventListener('mousedown', (e: any) => {
if (!isResizing) return;
isMousedown = true;
});
// 按住鼠标移动改变尺寸
dialogDom.parentElement.addEventListener('mousemove', (e: any) => {
const domWidth = dialogDom.clientWidth;
const domHeight = dialogDom.clientHeight;
const domTop = dialogDom.offsetTop;
const domLeft = dialogDom.offsetLeft;
const dialogBoxX = e.pageX - dialogBoxDom.offsetLeft;
const dialogBoxY = e.pageY - dialogBoxDom.offsetTop;
const minWidth = 100;
const minHeight = 100;
// 拖拽
if(isDrag) {
// console.log(dialogDom.clientWidth)
dialogDom.style.left = dialogBoxX - dragPosition.x + 'px';
dialogDom.style.top = dialogBoxY - dragPosition.y + 'px';
}
if (!isMousedown) return;
switch (isResizing) {
case 'top-left':
moveTop();
moveLeft();
break;
case 'bottom-right':
moveBottom();
moveRight();
break;
case 'top-right':
moveTop();
moveRight();
break;
case 'bottom-left':
moveBottom();
moveLeft();
break;
case 'left':
moveLeft();
break;
case 'right':
moveRight();
break;
case 'top':
moveTop();
break;
case 'bottom':
moveBottom();
break;
default:
break;
}
function moveLeft() {
const width = domWidth + domLeft - dialogBoxX;
if (domWidth < minWidth && width < domWidth) return;
dialogDom.style.left = dialogBoxX + 'px';
dialogDom.style.width = width + 'px';
}
function moveRight() {
const width = dialogBoxX - domLeft;
if (domWidth < minWidth && width < domWidth) return;
dialogDom.style.width = width + 'px';
}
function moveTop() {
const height = domHeight + domTop - dialogBoxY;
if (domHeight < minHeight && height < domHeight) return;
dialogDom.style.top = dialogBoxY + 'px';
dialogDom.style.height = height + 'px';
}
function moveBottom() {
const height = dialogBoxY - domTop;
if (domHeight < minHeight && height < domHeight) return;
dialogDom.style.height = height + 'px';
}
});
// 鼠标抬起
dialogDom.parentElement.addEventListener('mouseup', (e: any) => {
isDrag = false;
isMousedown = false;
});
} else {
setTimeout(() => {
addEventFun();
}, 1000);
}
}
}
export default dialogDrag
main.ts
import { createApp } from 'vue'
import AppVue from './AppVue.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import dialogDrag from "./util/dialog"
createApp(AppVue)
.use(ElementPlus)
.directive('dialogdrag', {
mounted(el, binding) {
dialogDrag(el, binding)
}
})
.mount('#app')
.$nextTick(() => {
postMessage({ payload: 'removeLoading' }, '*')
})
demo.vue
<template>
<el-dialog v-model="show" title="" width="50%" :append-to-body= :close-on-click-modal="false" :show-close="false">
<div v-dialogdrag>内容</div>
</el-dialog>
</template>