Element实现el-dialog弹框移动、全屏功能
1、在Vue项目中src/utils目录中创建dialog.js,用来定义draggable-dialog;
import Vue from 'vue'
Vue.directive('draggable-dialog', { // 属性名称draggable-dialog,前面加v- 使用
bind(el, binding, vnode) {
const dialogHeaderEl = el.querySelector('.el-dialog__header')
const dragDom = el.querySelector('.el-dialog')
dialogHeaderEl.style.cssText += ';cursor:move;'
dragDom.style.cssText += ';top:0px;'
// 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
const getStyle = (function () {
if (window.document.currentStyle) {
return (dom, attr) => dom.currentStyle[attr]
} else {
return (dom, attr) => getComputedStyle(dom, false)[attr]
}
})()
dialogHeaderEl.onmousedown = (e) => {
// 鼠标按下,计算当前元素距离可视区的距离
const disX = e.clientX - dialogHeaderEl.offsetLeft
const disY = e.clientY - dialogHeaderEl.offsetTop
const dragDomWidth = dragDom.offsetWidth
// const dragDomHeight = dragDom.offsetHeight
const screenWidth = document.body.clientWidth
const screenHeight = document.body.clientHeight
const minDragDomLeft = dragDom.offsetLeft
const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth
const minDragDomTop = dragDom.offsetTop
// const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomHeight
const maxDragDomTop = screenHeight - dragDom.offsetTop// 不需要-dragDomHeight
// 获取到的值带px 正则匹配替换
let styL = getStyle(dragDom, 'left')
let styT = getStyle(dragDom, 'top')
if (styL.includes('%')) {
styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100)
styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100)
} else {
styL = +styL.replace(/\px/g, '')
styT = +styT.replace(/\px/g, '')
}
document.onmousemove = function (e) {
// 通过事件委托,计算移动的距离
let left = e.clientX - disX
let top = e.clientY - disY
// 边界处理
if (-(left) > minDragDomLeft) {
left = -minDragDomLeft
} else if (left > maxDragDomLeft) {
left = maxDragDomLeft
}
if (-(top) > minDragDomTop) {
top = -minDragDomTop
} else if (top > maxDragDomTop) {
top = maxDragDomTop
}
// 移动当前元素
dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`
// emit onDrag event
vnode.child.$emit('draggable-dialog')
}
document.onmouseup = function (e) {
document.onmousemove = null
document.onmouseup = null
}
}
}
})
2、 在main.js文件中引入dialog.js,代码如下:
import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import '@/utils/dialog.js'
Vue.use(ElementUI)
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
3、页面中的el-dialog标签上添加v-draggable-dialog
<el-dialog
id="dragDialog"
v-draggable-dialog
:fullscreen="dialogFullScreen"
:v-if="showDialog"
:visible.sync="showDialog"
title="查看"
>
<template slot="title">
<div class="custom_dialog_header">
<span class="el_dialog_title">查看详情</span>
<div class="custom_dialog_menu" @click="screenClick">
<i class="el-icon-full-screen"></i>
</div>
</div>
</template>
<div>展示内容</div >
</el-dialog>
//全屏 定义属性
dialogFullScreen: false
showDialog: false
//全屏用的方法
screenClick() {
this.$nextTick(() => {
this.dialogFullScreen = !this.dialogFullScreen
const dialog = document.querySelector('#dragDialog .el-dialog')
dialog.style.left = '0'
dialog.style.top = '0'
})
}
//如果 移动弹窗位置,第二次点击没有居中,可以在打开弹窗时,调用recoveryPosition方法
recoveryPosition() {
this.$nextTick(() => {
const dialog = document.querySelectorAll(
'.el-dialog__wrapper .el-dialog'
)
if (dialog.length > 0) {
dialog.forEach((item) => {
item.style.left = '0'
item.style.top = '0'
})
}
})
},
//全屏样式
::v-deep.custom_dialog_header {
display: flex;
justify-content: space-between;
}
::v-deep .custom_dialog_menu {
padding: 7px 30px 0 0;
}
::v-deep .custom_dialog_menu i {
color: #909399;
font-size: 15px;
}
::v-deep.el-icon-full-screen {
cursor: pointer;
}
说明:v-draggable-dialog 是移动位置用的 fullscreen 是全屏的属性 添加全屏功能 要加id dragDialog