237 lines
6.4 KiB
JavaScript
237 lines
6.4 KiB
JavaScript
/** 弹窗支持拖拽 license by http://eleadmin.com */
|
|
|
|
/**
|
|
* 获取父元素
|
|
* @param el
|
|
* @param parentClass
|
|
* @returns
|
|
*/
|
|
function queryParentByClass(el, parentClass) {
|
|
if(!el){
|
|
return;
|
|
}
|
|
if (el === document) {
|
|
return;
|
|
}
|
|
if (el.classList.contains(parentClass)) {
|
|
return el;
|
|
}
|
|
return queryParentByClass(el.parentNode, parentClass);
|
|
}
|
|
|
|
/**
|
|
* 获取样式
|
|
* @param el
|
|
* @returns
|
|
*/
|
|
function getCurrentStyle(el) {
|
|
return el.currentStyle || window.getComputedStyle(el, null) || {};
|
|
}
|
|
|
|
/**
|
|
* 初始化modal样式
|
|
* @param modalEl
|
|
*/
|
|
function initModalStyle(modalEl) {
|
|
modalEl.style.top = modalEl.offsetTop + 'px';
|
|
modalEl.style.left = modalEl.offsetLeft + 'px';
|
|
modalEl.style.bottom = 'auto';
|
|
modalEl.style.right = 'auto';
|
|
modalEl.style.margin = 0;
|
|
modalEl.style.position = 'relative';
|
|
modalEl.style.display = 'inline-block';
|
|
}
|
|
|
|
/**
|
|
* 弹窗最大化切换
|
|
* @param btnEl
|
|
* @param fullscreen
|
|
*/
|
|
function toggleFullscreen(btnEl, fullscreen) {
|
|
const modalEl = queryParentByClass(btnEl, 'ant-modal');
|
|
if (modalEl) {
|
|
const wrapEl = modalEl.parentNode, fullClass = 'ele-modal-wrap-fullscreen';
|
|
if (typeof fullscreen === 'undefined') {
|
|
wrapEl.classList.toggle(fullClass);
|
|
} else if (fullscreen) {
|
|
wrapEl.classList.add(fullClass);
|
|
} else {
|
|
wrapEl.classList.remove(fullClass);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 弹窗支持拖动
|
|
*/
|
|
export function modalMovable() {
|
|
document.addEventListener('mousedown', function (event) {
|
|
const headerEl = queryParentByClass(event.target, 'ant-modal-header');
|
|
if (!headerEl) {
|
|
return;
|
|
}
|
|
const modalEl = headerEl.parentNode.parentNode, wrapEl = modalEl.parentNode;
|
|
const moveOut = wrapEl.classList.contains('ele-modal-move-out');
|
|
if (!wrapEl.classList.contains('ele-modal-movable') && !moveOut) {
|
|
return;
|
|
}
|
|
if (wrapEl.classList.contains('ele-modal-wrap-fullscreen')) {
|
|
return;
|
|
}
|
|
modalEl.style.userSelect = 'none';
|
|
initModalStyle(modalEl);
|
|
// 获取原始位置
|
|
const downX = event.clientX;
|
|
const downY = event.clientY;
|
|
const downOL = modalEl.offsetLeft;
|
|
const downOT = modalEl.offsetTop;
|
|
|
|
// 鼠标移动事件
|
|
const mousemoveFn = function (e) {
|
|
let l = e.clientX - downX + downOL;
|
|
let t = e.clientY - downY + downOT;
|
|
// 边界判断
|
|
if (!moveOut) {
|
|
const screenWidth = document.documentElement.clientWidth || document.body.clientWidth;
|
|
let limitL = screenWidth - modalEl.clientWidth;
|
|
if (l < 1) {
|
|
l = 1;
|
|
} else if (l > limitL - 1) {
|
|
l = limitL - 1;
|
|
}
|
|
const screenHeight = document.documentElement.clientHeight || document.body.clientHeight;
|
|
let limitT = screenHeight - modalEl.clientHeight;
|
|
if (t > limitT - 2) {
|
|
t = limitT - 2;
|
|
}
|
|
if (t < 1) {
|
|
t = 1;
|
|
}
|
|
}
|
|
// 移动dialog
|
|
modalEl.style.left = l + 'px';
|
|
modalEl.style.top = t + 'px';
|
|
}
|
|
|
|
// 鼠标抬起事件
|
|
const mouseupFn = function () {
|
|
modalEl.style.userSelect = null;
|
|
document.removeEventListener('mousemove', mousemoveFn);
|
|
document.removeEventListener('mouseup', mouseupFn);
|
|
};
|
|
|
|
// 添加鼠标事件监听
|
|
document.addEventListener('mousemove', mousemoveFn);
|
|
document.addEventListener('mouseup', mouseupFn);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 弹窗支持拉伸
|
|
*/
|
|
export function modalResizable() {
|
|
document.addEventListener('mousedown', function (event) {
|
|
const modalEl = queryParentByClass(event.target, 'ant-modal');
|
|
if (!modalEl) {
|
|
return;
|
|
}
|
|
const wrapEl = modalEl.parentNode;
|
|
if (!wrapEl.classList.contains('ele-modal-resizable')) {
|
|
return;
|
|
}
|
|
if (wrapEl.classList.contains('ele-modal-wrap-fullscreen')) {
|
|
return;
|
|
}
|
|
const limitX = modalEl.clientWidth + modalEl.offsetLeft - wrapEl.scrollLeft;
|
|
const limitY = modalEl.clientHeight + modalEl.offsetTop - wrapEl.scrollTop;
|
|
if (
|
|
event.clientX > limitX ||
|
|
limitX - event.clientX > 10 ||
|
|
event.clientY > limitY ||
|
|
limitY - event.clientY > 10
|
|
) {
|
|
return;
|
|
}
|
|
modalEl.style.userSelect = 'none';
|
|
initModalStyle(modalEl);
|
|
// 获取原始位置
|
|
const downX = event.clientX;
|
|
const downY = event.clientY;
|
|
const downW = modalEl.clientWidth;
|
|
const downH = modalEl.clientHeight;
|
|
|
|
// 鼠标移动事件
|
|
const mousemoveFn = function (e) {
|
|
const w = e.clientX - downX + downW;
|
|
const h = e.clientY - downY + downH;
|
|
const nw = (w < 260 ? 260 : w) + 'px';
|
|
// 移动dialog
|
|
modalEl.style.width = nw;
|
|
modalEl.style.maxWidth = nw;
|
|
modalEl.style.minWidth = nw;
|
|
modalEl.style.height = (h < 160 ? 160 : h) + 'px';
|
|
}
|
|
|
|
// 鼠标抬起事件
|
|
const mouseupFn = function () {
|
|
modalEl.style.userSelect = null;
|
|
document.removeEventListener('mousemove', mousemoveFn);
|
|
document.removeEventListener('mouseup', mouseupFn);
|
|
};
|
|
|
|
// 添加鼠标事件监听
|
|
document.addEventListener('mousemove', mousemoveFn);
|
|
document.addEventListener('mouseup', mouseupFn);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 弹窗自动置顶
|
|
*/
|
|
export function modalAutoSetTop() {
|
|
document.addEventListener('mousedown', function (event) {
|
|
const modalEl = queryParentByClass(event.target, 'ant-modal');
|
|
if (!modalEl) {
|
|
return;
|
|
}
|
|
const wrapEl = modalEl.parentNode;
|
|
if (!wrapEl.classList.contains('ele-modal-multiple')) {
|
|
return;
|
|
}
|
|
const wrapperEls = document.querySelectorAll('.ant-modal-wrap');
|
|
let zIndex = Number(getCurrentStyle(wrapEl).zIndex || 1000), newZIndex = zIndex;
|
|
for (let i = 0; i < wrapperEls.length; i++) {
|
|
const index = Number(getCurrentStyle(wrapperEls[i]).zIndex || 1000);
|
|
if (wrapperEls[i] !== wrapEl && index >= newZIndex) {
|
|
newZIndex = index + 1;
|
|
}
|
|
}
|
|
if (newZIndex > zIndex) {
|
|
wrapEl.style.zIndex = String(newZIndex);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 弹窗支持最大化最小化
|
|
*/
|
|
export function modalMaximizable() {
|
|
document.addEventListener('click', function (event) {
|
|
const btnEl = event.target.tagName === 'svg' ? event.target.parentNode : event.target;
|
|
if (btnEl.classList.contains('ele-modal-icon-expand')) {
|
|
toggleFullscreen(btnEl, true);
|
|
} else if (btnEl.classList.contains('ele-modal-icon-compress')) {
|
|
toggleFullscreen(btnEl, false);
|
|
}
|
|
});
|
|
}
|
|
|
|
export default {
|
|
install() {
|
|
modalMovable();
|
|
modalResizable();
|
|
modalAutoSetTop();
|
|
modalMaximizable();
|
|
}
|
|
}
|