当前位置: 首页 > article >正文

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


http://www.kler.cn/a/564536.html

相关文章:

  • Ubuntu24.04设置静态IP地址
  • 多线程之旅:锁策略
  • 使用DeepSeek/chatgpt等AI工具辅助网络协议流量数据包分析
  • 大语言模型概念科普
  • 计算机毕业设计 ——jspssm510springboot 的人职匹配推荐系统
  • uniapp vue3实现的一款数字动画调节器件,支持长按、单点操作,提供丝滑的增减动画效果
  • Ecode前后端传值
  • 3 年→ 资深开发速通计划 序言
  • AndroidManifest.xml文件的作用
  • VSCode轻松调试运行.Net 8.0 Web API项目
  • 前端TypeScript 面试题及参考答案
  • leetcode 214. 最短回文串
  • 本地部署语言大模型deepseek完整步骤
  • SheetDataMerge合并工作表(excel)内多行同类数据的小工具。
  • C语言基础之【指针】(上)
  • 快速排序与归并排序模板
  • 微信小程序换行符真机不生效问题
  • DeepSeek再推开源力作,DeepEP高效通信库来袭
  • ES6模块化详解:导入与导出方式
  • 空中机械臂仿真问题