????????該篇為前一篇“Element-UI - 解決el-table中圖片懸浮被遮擋問題”的優化升級部分,解決當圖片位于頁面底部時,顯示不全問題優化。
????????Vue.directive鉤子函數已在上一篇中詳細介紹,不清楚的朋友可以翻看上一篇,?“Element-UI - 解決el-table中圖片懸浮被遮擋問題”的地址:Element-UI - 解決el-table中圖片懸浮被遮擋問題_el-badge el-table 被遮擋-CSDN博客
一、瀏覽器窗口
? ? ? ? 瀏覽器窗口的寬和高分別通過window.innerWidth和window.innerHeight獲取,如最底部圖片,可以通過獲取彈框中圖片高度,進行對比是否超出window.innerHeight; 如果超出,則減于圖片高度,進行底部對齊顯示。
二、彈框中圖片高度獲取
? ? ? ? 在上一篇中,在彈框封裝類中定義了imgBox屬性,用于記錄彈框中圖片DOM節點對象,所以可以在執行resetPosition(boundingClientRect)函數時,可以通過this.imgBox.height獲取彈框中圖片的高度。
? ? ? ? 控制臺中顯示彈框中圖片高度,如下圖:
三、實現圖片上移
? ? ? ? 通過上述了解后,知道了如何判斷圖片是否超出底位置,如果超出了,則需要將位置top減掉彈框實際高度(圖片高度 + 彈框內填充),進行上移即可。
? ? ? ? 修改后的resetPosition函數代碼如下:
/*** 重新指定彈框位置* @param {Object} boundingClientRect*/resetPosition(boundingClientRect){// 彈框實際高度const height = this.imgBox.height + this.dialogPadding * 2;// 判斷圖片是否超出底部可見范圍if( boundingClientRect.top + height >= window.innerHeight){// top減于彈框實際高度this.sDialog.style.top = (boundingClientRect.top - height) + "px";}// 未超出else{this.sDialog.style.top = (boundingClientRect.top - this.dialogPadding) + "px";}this.sDialog.style.left = (boundingClientRect.width + boundingClientRect.left) + "px";}
? ? ? ? 此時底部圖片則已被修正,可以底部對齊顯示了,如下圖:
四、完整代碼
1.頁面代碼
import sDialog from './suspendedDialog.js'
export default {data(){return {tableData: [{name: "Angular", thumb: require("@/assets/angular.jpg"), createtime: "2024/6/15", updatetime: "2024/6/15"},{name: "VueJs", thumb: require("@/assets/logo.png"), createtime: "2024/6/15", updatetime: "2024/6/15"},{name: "NuxtJs", thumb: require("@/assets/nuxtjs.jpg"), createtime: "2024/6/15", updatetime: "2024/6/15"},{name: "React", thumb: require("@/assets/react.jpg"), createtime: "2024/6/15", updatetime: "2024/6/15"},{name: "Dog", thumb: require("@/assets/dog.jpg"), createtime: "2024/6/15", updatetime: "2024/6/15"}]}},directives: {// 自定義懸浮v-suspendedsuspended: {bind: (el) => {// 初始化懸浮框sDialog.initialDom();// 鼠標經過圖片并未移出時執行回調函數el.addEventListener('mouseenter', function(e) {// 顯示懸浮彈框,顯示后獲取相應的參數信息sDialog.toggle(true, () => {sDialog.setImgUrl(el.src); // 修改新的圖片地址sDialog.resetPosition(el.getBoundingClientRect()); // 修正彈框位置});});// 鼠標移出圖片區域時,隱藏懸浮彈框el.addEventListener('mouseleave', () => sDialog.toggle(false));}}},// end
}
2.封裝類(suspendedDialog.js)
/** 定義彈框類*/
class SuspendedDialog{constructor(){this.idName = "suspended-dialog"; // 定義容器ID選擇器名稱this.innerClassName = "inner"; // 內容器類選擇器名稱this.imgClassName = "imgs"; // 圖片節點類選擇器名稱this.dialogWidth = 240; // 外容器寬度this.dialogPadding = 12; // 外容器內填充this.sDialog = document.createElement('div'); // 外層容器this.innerBox = document.createElement('div'); // 內容器對象this.imgBox = document.createElement('img'); // 圖片節點對象}/*** 初始化DOM,并添加到body中*/initialDom(){const sDialog = document.getElementById(this.idName); // 查詢節點// 如果節點存在,則結束后續操作if(sDialog) return;// 初始經屬性this.sDialog.id = this.idName;this.innerBox.classList.add(this.innerClassName);this.imgBox.classList.add(this.imgClassName);// 將DOM追加到對應容器中this.innerBox.append(this.imgBox);this.sDialog.append(this.innerBox);document.body.append(this.sDialog);// 追加事件this.addEvent();}/*** 修改圖片路徑* @param {Object} _url*/setImgUrl(_url){this.imgBox.src = _url;}/*** 添加監聽事件*/addEvent(){this.sDialog.addEventListener('mouseenter', e => this.toggle(true)); // 鼠標移入懸浮框區域時保持顯示this.sDialog.addEventListener('mouseleave', e => this.toggle(false)); // 鼠標移出懸浮框區域時隱藏}/*** 顯示與隱藏* @param {Object} flag* @param {Object} callback 回調函數*/toggle(flag, callback = () => {}){if(flag && 'block'!=this.sDialog.style.display){this.sDialog.style.display = 'block';callback();} else if(!flag && 'none'!=this.sDialog.style.display){this.sDialog.style.display = 'none';callback();}}/*** 重新指定彈框位置* @param {Object} boundingClientRect*/resetPosition(boundingClientRect){// 彈框實際高度const height = this.imgBox.height + this.dialogPadding * 2;// 判斷圖片是否超出底部可見范圍if(boundingClientRect.top + height >= window.innerHeight){// top減于彈框實際高度this.sDialog.style.top = (boundingClientRect.top - height) + "px";}// 未超出else{this.sDialog.style.top = (boundingClientRect.top - this.dialogPadding) + "px";}this.sDialog.style.left = (boundingClientRect.width + boundingClientRect.left) + "px";}
}
export default new SuspendedDialog();
? ? ? ? 另外,圖片除了底部超出可見范圍,也會出現左側或右側超出可見范圍,則可以通過window.innerWidth進行判斷處理,計算方式差不多,這里就不再闡述。