dragPlus.js
文件内容
export default {
bind(el, binding, vnode, oldVnode) {
const {
arg, value } = binding;
//弹框可拉伸最小宽高
let minWidth = 400;
let minHeight = 300;
//初始非全屏
let isFullScreen = false;
// 初始非最小化
let isMinimum = false;
//当前宽高
let nowWidth = 0;
let nowHight = 0;
// 是否收缩
let isTakeIn = false;
//当前顶部高度
let nowMarginTop = 0;
//获取弹框头部(这部分可双击全屏)
const dialogHeaderEl = el.querySelector('.el-dialog__header');
//弹窗
const dragDom = el//.querySelector('.el-dialog');
const dragDomDialog = el.querySelector('.el-dialog')
//给弹窗加上overflow auto;不然缩小时框内的标签可能超出dialog;
dragDomDialog.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) {
dragDom.style.opacity = '0.8'
// 通过事件委托,计算移动的距离
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})
dragDom.style.bottom = 'auto'
};
document.onmouseup = function (e) {
document.onmousemove = null;
document.onmouseup = null;
dragDom.style.opacity = '1'
};
}
//(右上方)还原窗口大小效果不想要可以注释
let resetBodyEL = document.createElement("i");
//(右上方)收缩窗口大小效果不想要可以注释
let takeInBodyEL = document.createElement("i");
dialogHeaderEl.appendChild(takeInBodyEL);
//在弹窗右下角加上一个10-10px的控制块
takeInBodyEL.style.cursor = 'pointer';
takeInBodyEL.style.position = 'absolute';
takeInBodyEL.style.height = '10px';
takeInBodyEL.style.width = '10px';
takeInBodyEL.style.right = '65px';
takeInBodyEL.className = 'el-dialog__close el-icon el-icon-arrow-up historical-trend-icon'
takeInBodyEL.style.top = '20px';
takeInBodyEL.onclick = (e) => {
// 动画过渡
el.style.transition = 'width 0.75s,height 0.75s'
isTakeIn = true;
nowHight = dragDom.clientHeight;
nowWidth = dragDom.clientWidth;
const headerW = dialogHeaderEl.clientWidth
const dialogBodyEl = el.querySelector('.el-dialog > .el-dialog__body');
dialogBodyEl.style.display = 'none'
const dialogFooterEl = el.querySelectorAll('.el-dialog > .el-dialog__footer');
if (dialogFooterEl && dialogFooterEl.length > 0) dialogFooterEl[dialogFooterEl.length - 1].style.display = 'none'
el.style.height = dialogHeaderEl.clientHeight + 'px'
el.style.width = headerW + 'px'
takeInBodyEL.style.display = 'none'
resetBodyEL.style.display = 'block'
}
dialogHeaderEl.appendChild(resetBodyEL);
resetBodyEL.style.cursor = 'pointer';
resetBodyEL.style.position = 'absolute';
resetBodyEL.style.height = '10px';
resetBodyEL.style.width = '10px';
resetBodyEL.style.right = '65px';
resetBodyEL.className = 'el-dialog__close el-icon el-icon-arrow-down historical-trend-icon'
resetBodyEL.style.top = '20px';
resetBodyEL.style.display = 'none'
resetBodyEL.onclick = (e) => {
el.style.transition = 'width 0.75s,height 0.75s'
isTakeIn = false;
el.style.height = nowHight + 'px'
el.style.width = nowWidth + 'px'
const dialogBodyEl = el.querySelector('.el-dialog > .el-dialog__body');
const dialogFooterEl = el.querySelectorAll('.el-dialog > .el-dialog__footer');
dialogBodyEl.style.display = 'block'
if (dialogFooterEl && dialogFooterEl.length > 0) dialogFooterEl[dialogFooterEl.length - 1].style.display = 'block'
takeInBodyEL.style.display = 'block'
resetBodyEL.style.display = 'none'
}
//拉伸(右上方)最小化效果不想要可以注释
let resizeETR = document.createElement("i");
dialogHeaderEl.appendChild(resizeETR);
//在弹窗右下角加上一个10-10px的控制块
resizeETR.style.cursor = 'pointer';
resizeETR.style.position = 'absolute';
resizeETR.style.height = '10px';
resizeETR.style.width = '10px';
resizeETR.style.right = '45px';
resizeETR.className = 'el-dialog__close el-icon el-icon-minus historical-trend-icon'
resizeETR.style.top = '20px';
resizeETR.onclick = (e) => {
takeInBodyEL.style.display = 'none'
resetBodyEL.style.display = 'none'
el.style.transition = 'width 0.75s,height 0.75s'
if (!isMinimum && !isTakeIn) {
nowHight = dragDom.clientHeight;
nowWidth = dragDom.clientWidth;
}
const dialogBodyEl = el.querySelector('.el-dialog > .el-dialog__body');
dialogBodyEl.style.display = 'none'
const dialogFooterEl = el.querySelectorAll('.el-dialog > .el-dialog__footer');
if (dialogFooterEl && dialogFooterEl.length > 0) dialogFooterEl[dialogFooterEl.length - 1].style.display = 'none'
el.style.height = dialogHeaderEl.clientHeight + 'px'
el.style.width = minWidth + 'px'
resizeETR.className = ''
isMinimum = true;
}
dialogHeaderEl.onmousedown = moveDown;
//双击(头部)效果不想要可以注释
dialogHeaderEl.ondblclick = (e) => {
el.style.transition = 'width 0.75s,height 0.75s'
const dialogFooterEl = el.querySelectorAll('.el-dialog > .el-dialog__footer');
if (dialogFooterEl && dialogFooterEl.length > 0) dialogFooterEl[dialogFooterEl.length - 1].style.display = 'block'
if (isFullScreen == false) {
if (isMinimum) {
dragDom.style.height = nowHight + 'px'
dragDom.style.width = nowWidth + 'px'
resizeETR.className = 'el-dialog__close el-icon el-icon-minus historical-trend-icon'
const dialogBodyEl = el.querySelector('.el-dialog > .el-dialog__body');
dialogBodyEl.style.display = 'block'
takeInBodyEL.style.display = 'block'
isMinimum = false;
} else {
nowHight = dragDom.clientHeight;
nowWidth = dragDom.clientWidth;
dragDom.style.height = "100VH";
dragDom.style.width = "100VW";
isFullScreen = true;
dialogHeaderEl.style.cursor = 'initial';
dialogHeaderEl.onmousedown = null;
}
nowMarginTop = dragDom.style.marginTop;
dragDom.style.left = 0;
dragDom.style.top = 0;
dragDom.style.marginTop = 0;
} else {
dragDom.style.height = "auto";
dragDom.style.width = nowWidth + 'px';
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) => {
el.style.transition = 'none'
// 记录初始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) => {
el.style.transition = 'none'
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) {
} else {
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) {
// } else {
// 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) {
el.style.transition = 'none'
e.preventDefault(); // 移动时禁用默认事件
//底部鼠标拖拽位置
// if (ELscrollTop + clientY > EloffsetTop + elH - 20 && ELscrollTop + clientY < EloffsetTop + elH) {
//往上拖拽
if (clientY > e.clientY) {
if (dragDom.clientHeight < minHeight) {
} else {
dragDom.style.height = elH - (clientY - e.clientY) * 2 + 'px';
}
}
//往下拖拽
if (clientY < e.clientY) {
dragDom.style.height = elH + (e.clientY - clientY) * 2 + 'px';
}
// }
};
//拉伸结束
document.onmouseup = function (e) {
document.onmousemove = null;
document.onmouseup = null;
};
}
// 滚动事件
dragDom.onscroll = (e) => {
const {
scrollLeft, scrollTop } = e.target
resizeEl.style.bottom = `-${
scrollTop}px`;
resizeEl.style.right = `-${
scrollLeft}px`;
resizeElR.style.right = `-${
scrollLeft}px`;
// resizeElL.style.left = `${scrollLeft}px`;
resizeElB.style.bottom = `-${
scrollTop}px`;
}
}
}
引入自定义指令
import Vue from "vue";
import dialogDragPlus from './dialog/dragPlus'
Vue.directive('dialogDragPlus', dialogDragPlus)
使用
<el-dialog v-dialog-drag-plus :visible.sync="dialogVisible" title="可拖拽和缩放的对话框">
<!-- 对话框内容 -->
</el-dialog>