一、對話框實作可拖拽功能
- 實作方法:vue的指令
- 使用方法:
1、将下列drag.js檔案放入代碼庫中;
2、在main.js中引入上述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 關閉 Dialog | true |
<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;