export const dialogResizeStandard = { mounted(el: any, binding: any, vnode: any) { const bValue = binding.value const localKeyMap: any = { positions: { 'can-resize3': 'cet-standard-positions', }, resize: { 'can-resize3': 'cet-standard-resize', }, } const resizeEvent = new CustomEvent('drag-resize', { detail: '尺寸变化', bubbles: false, }) // 初始化不最大化 el.fullscreen = false const winHeight = window.innerHeight // 弹框可拉伸最小宽高 const minWidth = 400 const minHeight = winHeight / 2 // 弹窗 const dragDom: any = document.querySelector('.' + binding.value) const dialogHeaderEl = dragDom.querySelector('.el-dialog__header') el.style.overflow = 'initial' dragDom.className += ' el-drag-dialog' // 给弹窗加上overflow auto;不然缩小时框内的标签可能超出dialog; // dragDom.style.overflow = 'auto' dragDom.style.background = '#fff' const keyboardPositions = localStorage.getItem(localKeyMap.positions[bValue]) const keyboardResize = localStorage.getItem(localKeyMap.resize[bValue]) if (keyboardPositions) { dragDom.style.left = JSON.parse(keyboardPositions).left || 0 dragDom.style.top = JSON.parse(keyboardPositions).top || 0 } if (keyboardResize) { const localW = JSON.parse(keyboardResize).width const localH = JSON.parse(keyboardResize).height localW && (dragDom.style.width = localW) localH && (dragDom.style.height = localH) } else { dragDom.style.height = minHeight + 100 + 'px' dragDom.style.width = '800px' } // 清除选择头部文字效果 // eslint-disable-next-line no-new-func 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 maxMin = document.createElement('button') maxMin.className += ' el-dialog__headerbtn el-dialog__minmax' maxMin.style.right = '40px' maxMin.style.color = '#ffffff' maxMin.title = el.fullscreen ? '还原' : '最大化' maxMin.innerHTML = '' dialogHeaderEl.insertBefore(maxMin, dialogHeaderEl.childNodes[1]) const moveDown = (e: any) => { // 鼠标按下,计算当前元素距离可视区的距离 const disX = e.clientX - dialogHeaderEl.offsetLeft const disY = e.clientY - dialogHeaderEl.offsetTop // 获取到的值带px 正则匹配替换 let styL: any, styT: any // 注意在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/g, '') styT = +sty.top.replace(/\px/g, '') } 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) { document.onmousemove = null document.onmouseup = null console.log('dragDom.style.left:', dragDom.style.left, dragDom.style.top) localStorage.setItem( localKeyMap.positions[bValue], JSON.stringify({ left: dragDom.style.left || 0, top: dragDom.style.top || 0, }) ) } } dialogHeaderEl.onmousedown = moveDown // 点击放大缩小效果 // maxMin.onclick = setMaxMin // 双击头部效果 // dialogHeaderEl.ondblclick = setMaxMin // 拉伸 const resizeEl = document.createElement('div') dragDom.appendChild(resizeEl) // 在弹窗右下角加上一个10-10px的控制块 resizeEl.style.cursor = 'se-resize' resizeEl.style.position = 'absolute' resizeEl.style.height = '10px' resizeEl.style.width = '10px' resizeEl.style.border = '3px solid transparent' resizeEl.style.borderRightColor = '#333' resizeEl.style.borderBottomColor = '#333' resizeEl.style.right = '0px' resizeEl.style.bottom = '0px' resizeEl.style.zIndex = '99' // 鼠标拉伸弹窗 resizeEl.onmousedown = (e) => { // 记录初始x位置 const clientX = e.clientX // 鼠标按下,计算当前元素距离可视区的距离 const disX = e.clientX - resizeEl.offsetLeft const disY = e.clientY - resizeEl.offsetTop const iframeMask = document.getElementById('my-iframe-mask') if (iframeMask) { iframeMask.style.display = 'block' } document.onmousemove = function (e) { e.preventDefault() // 移动时禁用默认事件 // 通过事件委托,计算移动的距离 const x = e.clientX - disX + (e.clientX - clientX) // 这里 由于elementUI的dialog控制居中的,所以水平拉伸效果是双倍 const y = e.clientY - disY // 比较是否小于最小宽高 dragDom.style.width = x > minWidth ? `${x}px` : minWidth + 'px' dragDom.style.height = y > minHeight ? `${y}px` : minHeight + 'px' // dragDom.style.width = `${x}px` // dragDom.style.height = `${y}px` // if (!hasSetBodyHight) { // const footerHeight = // dragDom.querySelector('.el-dialog__footer') && dragDom.querySelector('.el-dialog__footer').offsetHeight // dragDom.querySelector('.el-dialog__body').style.height = // 'calc(100% - ' + (dialogHeaderEl.offsetHeight + footerHeight) + 'px)' // hasSetBodyHight = true // } } // 拉伸结束 document.onmouseup = function (e) { document.onmousemove = null document.onmouseup = null localStorage.setItem( localKeyMap.resize[bValue], JSON.stringify({ width: dragDom.style.width || 'auto', height: dragDom.style.height || 'auto', }) ) el.dispatchEvent(resizeEvent) const iframeMask = document.getElementById('my-iframe-mask') if (iframeMask) { iframeMask.style.display = 'none' } } } }, }