ElementUI的el-dialog弹窗怎么设置可拖拽,可最大化
可直接自定义一条vue指令,vue页面直接绑定指令即可完成。
效果图如下:
```javascript
export default {
bind(el, binding, vnode, oldVnode) {
//初始非全屏
let isFullScreen = false;
//当前宽高
let nowWidth = 0;
let nowHeight = 0;
//当前顶部高度
let nowMarginTop = '0';
//获取弹框头部(这部分可双击全屏)
const dialogHeaderEl = el.querySelector('.el-dialog__header');
let hasSetBodyHeight = false;
//弹窗
const dragDom = el.querySelector('.el-dialog');
//给弹窗加上overflow auto;不然缩小时框内的标签可能超出dialog;
// dragDom.style.overflow = "auto";
//清除选择头部文字效果
dialogHeaderEl.onselectstart = new Function("return false");
// 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);
//头部插入最大化最小化元素
let maxMin = document.createElement("button");
maxMin.className += ' el-dialog__headerbtn el-dialog__minmax';
maxMin.style.right = '40px';
maxMin.style.color = '#409eff';
maxMin.title = '最大化';
maxMin.innerHTML =
'<i class="el-icon-full-screen" style="font-size: 16px; display: block; margin: 3px;" onMouseOver="this.style.color=\'#e94646\'" onMouseOut="this.style.color=\'#409eff\'"></i>';
dialogHeaderEl.insertBefore(maxMin, dialogHeaderEl.childNodes[1]);
let cls = dialogHeaderEl.childNodes[2];
let bodyHeight = 'auto';
// 窗口-最大化与还原
function setMaxMin() {
isFullScreen = !isFullScreen;
if (isFullScreen) {
let i = maxMin.querySelector('.el-icon-full-screen');
i.classList.remove('el-icon-full-screen');
i.classList.add('el-icon-crop');
maxMin.title = '还原';
bodyHeight = dragDom.querySelector('.el-dialog__body').offsetHeight + 'px';
nowWidth = dragDom.clientWidth;
nowHeight = dragDom.clientHeight;
nowMarginTop = dragDom.style.marginTop;
dragDom.style.left = 0;
dragDom.style.top = 0;
dragDom.style.height = "100VH";
dragDom.style.width = "100VW";
dragDom.style.margin = "0 auto";
dragDom.style.borderRadius = '0';
// dialogHeaderEl.style.cursor = 'initial';
if (!hasSetBodyHeight) {
dragDom.querySelector('.el-dialog__body').style.height = 'calc(100% - ' + dialogHeaderEl.offsetHeight + 'px)';
dragDom.querySelector('.el-dialog__body').style.overflow = "auto";
hasSetBodyHeight = true;
}
} else {
let i = maxMin.querySelector('.el-icon-crop');
i.classList.remove('el-icon-crop');
i.classList.add('el-icon-full-screen');
maxMin.innerHTML =
'<i class="el-icon-full-screen" style="font-size: 16px; display: block; margin: 3px;" onMouseOver="this.style.color=\'#e94646\'" onMouseOut="this.style.color=\'#409eff\'"></i>';
maxMin.title = '最大化';
dragDom.style.height = "auto";
if (dragDom.children[1] && dragDom.children[1].clientHeight === 0) {
dragDom.style.height = nowHeight + 'px';
}
dragDom.style.width = nowWidth + 'px';
dragDom.style.marginTop = nowMarginTop;
dragDom.style.marginBottom = '50px';
dragDom.style.borderRadius = '4px';
dragDom.querySelector('.el-dialog__body').style.overflow = "";
hasSetBodyHeight = false;
}
// 最大化最小化回调
if (binding.value) {
if (binding.value.fun) {
binding.value.fun({isFullScreen: isFullScreen});
}
}
}
//未设置参数的情况=默认隐藏放大缩小,不可点击 - 或者设置可放大缩小
maxMin.style.display = 'none';
dialogHeaderEl.ondblclick = null;
maxMin.onclick = null;
if (binding.value) {
if (!!binding.value.maxFlag) {
maxMin.style.display = 'initial';
maxMin.onclick = setMaxMin;
dialogHeaderEl.ondblclick = setMaxMin;
}
}
//关闭窗口后,恢复可能变高的el-dialog__body
cls.onclick = function () {
let a = dragDom.querySelector('.el-dialog__body').style.height = ""
}
// 窗口移动事件
const 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', '')
styT = +sty.top.replace('px', '')
}
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) {
const dragDom = el.querySelector('.el-dialog')
const offsetLeft = dragDom.offsetLeft
const offsetTop = dragDom.offsetTop
const left = Number(dragDom.style.left.replace('px', '')) + 8
const top = Number(dragDom.style.top.replace('px', ''))
const windowWidth = window.innerWidth - 16
const windowHeight = window.innerHeight
const offsetRight = offsetLeft + dragDom.offsetWidth - windowWidth
const offsetBottom = offsetTop + dragDom.offsetHeight - windowHeight
// if (offsetLeft < 0) {
// dragDom.style.left = (left - offsetLeft) + 'px'
// }
if (offsetTop < 3) {
dragDom.style.top = (top - offsetTop) + 'px'
}
// if (offsetRight > 0) {
// dragDom.style.left = (left - offsetRight) + 'px'
// }
let calcValue = dragDom.offsetHeight - 30
if (offsetBottom > calcValue) {
dragDom.style.top = (top - offsetBottom + dragDom.offsetHeight - 30) + 'px'
}
document.onmousemove = null
document.onmouseup = null
}
//return false不加的话可能导致黏连,就是拖到一个地方时div粘在鼠标上不下来,相当于onmouseup失效
return false
}
// 无传参数的情况-默认可拖拽窗口-未设置参数的情况,或者设置可拖拽的情况
el.style.overflow = 'hidden';
dialogHeaderEl.style.cursor = 'move'
dialogHeaderEl.onmousedown = moveDown;
// 设置窗口移动
if (binding.value) {
if (!!!binding.value.dragFlag) {
dialogHeaderEl.style.cursor = 'initial';
dialogHeaderEl.onmousedown = null;
// 不可拖拽的情况,设置弹窗外部可以自动滚动,
el.style.overflow = 'auto';
}
}
}
}
如何使用?
1.在main.js文件直接注入:
import elDragDialog from '@/directive/el-drag-dialog';
Vue.directive('el-drag-dialog', elDragDialog);
2.新建vue新页面:
<el-dialog v-el-drag-dialog>
…other UI content…
</el-dialog>
v-el-drag-dialog 无参情况:没有回调,可拖拽,不可最大化
fun: callBackMaxMin, // 最大化方法回调。
maxFlag:true, // 是否允许窗口最大化-默认不允许
dragFlag: false // 是否允许拖拽-默认可拖拽
// 存在参数的写法:
v-el-drag-dialog="{ fun: callBackMaxMin, maxFlag:true, dragFlag: false }"