el-dialog drag and drop implementation and the drag process. Some areas cannot be dragged, and the position is incorrect in full screen mode and the solution (general version)
The project template uses the vue-admin-element version
It has its own drag and drop method.
This is the method copied above dialogDrag.js
import Vue from 'vue' // v-dialogDrag: Pop-up window drag attribute (Key point!!! Add this attribute to the modal box and the modal box can be dragged) Vue.directive('dialogDrag', {<!-- --> // Property name dialogDrag, add v- in front of it to use 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;' // Get the original attributes ie dom element.currentStyle Firefox Google window.getComputedStyle(dom element, 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) => {<!-- --> // When the mouse is pressed, calculate the distance between the current element and the visible area 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// No need for -dragDomHeight //The obtained value has px regular matching and replacement 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) {<!-- --> //Calculate the distance moved through event delegation let left = e.clientX - disX let top = e.clientY - disY // Boundary processing if (-(left) > minDragDomLeft) {<!-- --> left = -minDragDomLeft } else if (left > maxDragDomLeft) {<!-- --> left = maxDragDomLeft } if (-(top) > minDragDomTop) {<!-- --> top = -minDragDomTop } else if (top > maxDragDomTop) {<!-- --> top = maxDragDomTop } //Move the current element dragDom.style.cssText + = `;left:${<!-- -->left + styL}px;top:${<!-- -->top + styT}px;` // emit onDrag event vnode.child.$emit('dragDialog') } document.onmouseup = function(e) {<!-- --> document.onmousemove = null document.onmouseup = null } } } })
Introduce it into main.js and you can use it. Change the location yourself
import '@/utils/dialogDrag' // Add drag and drop to global dialog
Add v-dialogDrag on el-dialog to achieve the drag effect
<el-dialog v-dialogDrag></el-dialog>
Existing problems
1. When dragging, some areas cannot be dragged, and full-screen dragging is not involved
Solution: I won’t explain it. Just copy it and replace the content of dialogDrag.js
import Vue from 'vue' // v-dialogDrag: Pop-up window drag attribute (Key point!!! Add this attribute to the modal box and the modal box can be dragged) Vue.directive('dialogDrag', {<!-- --> // Property name dialogDrag, add v- in front of it to use 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;' // Get the original attributes ie dom element.currentStyle Firefox Google window.getComputedStyle(dom element, 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) => {<!-- --> // When the mouse is pressed, calculate the distance between the current element and the visible area 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// No need for -dragDomHeight //The obtained value has px regular matching and replacement 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) {<!-- --> //Calculate the distance moved through event delegation let left = e.clientX - disX let top = e.clientY - disY // Boundary processing if (-(left) > minDragDomLeft) {<!-- --> left = -minDragDomLeft } else if (left > maxDragDomLeft) {<!-- --> left = maxDragDomLeft } if (-(top) > minDragDomTop) {<!-- --> top = -minDragDomTop } else if (top > maxDragDomTop) {<!-- --> top = maxDragDomTop } //Move the current element dragDom.style.cssText + = `;left:${<!-- -->left + styL}px;top:${<!-- -->top + styT}px;` // emit onDrag event vnode.child.$emit('dragDialog') } document.onmouseup = function(e) {<!-- --> document.onmousemove = null document.onmouseup = null } } } })
The problem was solved after replacing
2. The full screen position is wrong after dragging
Solution: It’s very simple. When you click full screen, the setting position can be restored to the default
Add it to the method yourself
Note: Prevent affecting other el-dialog
We try to add id to el-dialog as much as possible
The id given here is dragDialog
// Prevent dragging from affecting the full screen and restore it to the center position this.$nextTick(() => {<!-- --> const dialog = document.querySelector('#dragDialog .el-dialog') dialog.style.left = '0' dialog.style.top = '0' })
Notice! ! ! Must be in synchronization situation, nextTick is used here
If it is useful, please give me a like and save it, I will be very happy, thank you