Vue 弹框拖拽功能实现及边界限制
export default { bind(el, binding, vnode, oldVnode) { // 弹框可拉伸最小宽高 const minWidth = 400; const minHeight = 300;
// 初始非全屏
let isFullScreen = true;
// 当前宽高
let nowWidth = 0;
let nowHight = 0;
// 当前顶部高度
let nowMarginTop = 0;
// 获取弹框头部(这部分可双击全屏)
const dialogHeaderEl = el.querySelector('.el-dialog__header');
// 弹窗
const dragDom = el.querySelector('.el-dialog');
// 给弹窗加上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);
const moveDown = (e) => {
// 鼠标按下,计算当前元素距离可视区的距离
const disX = e.clientX - dialogHeaderEl.offsetLeft;
const disY = e.clientY - dialogHeaderEl.offsetTop;
const winWidth = document.documentElement.clientWidth;
const winHeight = document.documentElement.clientHeight;
const maxWidth = winWidth - dragDom.offsetWidth;
const maxHeight = winHeight - dragDom.offsetHeight;
let styL, styT;
if (sty.left.includes('%')) {
styL = +winWidth * (+sty.left.replace(/%/g, '') / 100);
styT = +winHeight * (+sty.top.replace(/%/g, '') / 100);
} else {
styL = +sty.left.replace(/\px/g, '');
styT = +sty.top.replace(/\px/g, '');
}
document.onmousemove = function (e) {
let l = e.clientX - disX;
let t = e.clientY - disY;
if (l < 0) {
l = 0;
} else if (l > maxWidth) {
l = maxWidth;
}
if (t < 0) {
t = 0;
} else if (t > maxHeight) {
t = maxHeight;
}
dragDom.style.left = `${l + styL}px`;
dragDom.style.top = `${t + styT}px`;
};
document.onmouseup = function (e) {
document.onmousemove = null;
document.onmouseup = null;
};
};
dialogHeaderEl.onmousedown = moveDown;
// 双击头部全屏效果
dialogHeaderEl.ondblclick = (e) => {
if (isFullScreen) {
// 全屏状态下禁用拖拽事件
dialogHeaderEl.onmousedown = null;
// 设置新的宽高和位置
nowHight = dragDom.clientHeight;
nowWidth = dragDom.clientWidth;
nowMarginTop = dragDom.style.marginTop;
dragDom.style.height = '100%';
dragDom.style.width = '100%';
dragDom.style.marginTop = 0;
isFullScreen = false;
} else {
// 恢复原始大小和位置
dragDom.style.height = `${nowHight}px`;
dragDom.style.width = `${nowWidth}px`;
dragDom.style.marginTop = nowMarginTop;
isFullScreen = true;
// 重新启用拖拽事件
dialogHeaderEl.onmousedown = moveDown;
}
};
},
}; 加上不能拖拽出上下左右页面,加上放大后不能拖拽出上下左右页面
内容:需要在moveDown函数中添加边界判断,以保证弹框不能拖拽到页面外部。
具体方法是,获取当前窗口的宽高和弹框的宽高,然后在移动时判断当前位置是否超出边界,如果超出则将弹框的位置设置为边界值。
另外,在全屏状态下需要禁用双击头部的拖拽事件,并在恢复原始大小后重新启用。
代码示例:
const moveDown = (e) => { const disX = e.clientX - dialogHeaderEl.offsetLeft; const disY = e.clientY - dialogHeaderEl.offsetTop; const winWidth = document.documentElement.clientWidth; const winHeight = document.documentElement.clientHeight; const maxWidth = winWidth - dragDom.offsetWidth; const maxHeight = winHeight - dragDom.offsetHeight; let styL, styT;
if (sty.left.includes('%')) { styL = +winWidth * (+sty.left.replace(/%/g, '') / 100); styT = +winHeight * (+sty.top.replace(/%/g, '') / 100); } else { styL = +sty.left.replace(/\px/g, ''); styT = +sty.top.replace(/\px/g, ''); }
document.onmousemove = function (e) { let l = e.clientX - disX; let t = e.clientY - disY;
if (l < 0) {
l = 0;
} else if (l > maxWidth) {
l = maxWidth;
}
if (t < 0) {
t = 0;
} else if (t > maxHeight) {
t = maxHeight;
}
dragDom.style.left = `${l + styL}px`;
dragDom.style.top = `${t + styT}px`;
};
document.onmouseup = function (e) { document.onmousemove = null; document.onmouseup = null; }; };
dialogHeaderEl.onmousedown = moveDown;
dialogHeaderEl.ondblclick = (e) => { if (isFullScreen) { // 全屏状态下禁用拖拽事件 dialogHeaderEl.onmousedown = null;
// 设置新的宽高和位置
nowHight = dragDom.clientHeight;
nowWidth = dragDom.clientWidth;
nowMarginTop = dragDom.style.marginTop;
dragDom.style.height = '100%';
dragDom.style.width = '100%';
dragDom.style.marginTop = 0;
isFullScreen = false;
} else {
// 恢复原始大小和位置
dragDom.style.height = ${nowHight}px;
dragDom.style.width = ${nowWidth}px;
dragDom.style.marginTop = nowMarginTop;
isFullScreen = true;
// 重新启用拖拽事件
dialogHeaderEl.onmousedown = moveDown;
} };
原文地址: https://www.cveoy.top/t/topic/oKN9 著作权归作者所有。请勿转载和采集!