elementUi el-dialog 对话框实现可拖拽、去掉覆盖层、并可操作底层的按钮

8 篇文章 0 订阅
4 篇文章 0 订阅

一、对话框实现可拖拽功能

  • 实现方法:vue的指令
  • 使用方法:

1、将下列drag.js文件放入代码库中;
2、在main.js中引入上述drag.js文件;

 import 'src/libs/drag.js';

3、在el-dialog组件中加上指令

<el-dialog
	v-dialogDrags
	:visible="dialogShow"
>
</el-dialog>

src/libs/drag.js

import Vue from 'vue';

/*

*  使用方法:

*  将以下代码复制到一个js文件中,然后在入口文件main.js中import引入即可;

*  给elementUI的dialog上加上 v-dialogDrags

*  给dialog设置 :close-on-click-modal="false" , 禁止点击遮罩层关闭弹出层

*/

// 兼容ie,谷歌
// v-dialogDrags: 弹窗拖拽属性 (重点!!! 给模态框添加这个属性模态框就能拖拽了)
Vue.directive('dialogDrags', { // 属性名称dialogDrags,前面加v- 使用
    bind(el, binding, vnode, oldVnode) {
        const dialogHeaderEl = el.querySelector('.el-dialog__header');
        const dragDom = el.querySelector('.el-dialog');
        dialogHeaderEl.style.cssText += ';cursor:move;';

        // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
        const sty = (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 screenWidth = document.body.clientWidth; // body当前宽度
            const screenHeight = document.documentElement.clientHeight; // 可见区域高度(应为body高度,可某些环境下无法获取)

            const dragDomWidth = dragDom.offsetWidth; // 对话框宽度
            const dragDomheight = dragDom.offsetHeight; // 对话框高度

            // 获取到的值带px 正则匹配替换
            let styL = sty(dragDom, 'left');
            let styT = sty(dragDom, 'top');

            // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
            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 + styL;
                let top = e.clientY - disY + styT;

                // 边界处理
                if (left < 0) {
                    left = 0;
                }

                if (left > screenWidth - dragDomWidth) {
                    left = screenWidth - dragDomWidth;
                }

                if (top < 0) {
                    top = 0;
                }
                if (top > screenHeight - dragDomheight) {
                    top = screenHeight - dragDomheight;
                }

                // 移动当前元素
                dragDom.style.cssText += `;left:${left}px;top:${top}px;`;
            };

            document.onmouseup = function (e) {
                document.onmousemove = null;
                document.onmouseup = null;
            };
        };
    }
});

二、对话框去掉覆盖层可操作底层的按钮功能

1、首先使用elementUi自带的两个参数

参数说明默认值
modal是否需要遮罩层true
close-on-click-modal是否可以通过点击 modal 关闭 Dialogtrue
<el-dialog
	v-dialogDrags
	:visible="dialogShow"
	:modal="false"
	:close-on-click-modal="false"
>
</el-dialog>

这样操作后发现灰色的遮罩层确实去掉了,但是通过审查元素查看还是有一层透明的覆盖层的,而且这时候也无法点击底部的按钮;

2、使用css3属性 pointer-events

pointer-events:none
元素永远不会成为鼠标事件的target。但是,当其后代元素的pointer-events属性指定其他值时,鼠标事件可以指向后代元素,在这种情况下,鼠标事件将在捕获或冒泡阶段触发父元素的事件侦听器。
简单的说就是点击事件可以穿透本元素,作用于下层的元素;

pointer-events:auto
与pointer-events属性未指定时的表现效果相同

// 覆盖层元素增加可穿透点击事件
.el-dialog__wrapper
    pointer-events:none;
// 弹窗层元素不可穿透点击事件(不影响弹窗层元素的点击事件)
.el-dialog
    pointer-events:auto;
相关推荐

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页

打赏作者

程序媛啊啊啊

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值