這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 在我們開發項目中,經常會遇到預覽圖片的需求。也就是點擊圖片,會全屏顯示該圖片。需求很簡單,但是如何讓實現更優雅就需要花點心思了。 最終效果圖 基礎版本 實現方式 點擊圖片,創建蒙層,克隆圖片 將圖片添加定位屬性,並添加到蒙層中 將蒙層添加 ...
這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
在我們開發項目中,經常會遇到預覽圖片的需求。也就是點擊圖片,會全屏顯示該圖片。需求很簡單,但是如何讓實現更優雅就需要花點心思了。
最終效果圖
基礎版本
實現方式
- 點擊圖片,創建蒙層,克隆圖片
- 將圖片添加定位屬性,並添加到蒙層中
- 將蒙層添加到body中
觀察下圖發現,雖然實現了需求,但是動畫很生硬,我們作為前端開發工程師,得對得起工程師
的身份,需要有工匠精神,接下來將介紹如何實現優雅的圖片預覽效果。
效果圖
代碼
<!DOCTYPE html> <html lang="en"> <head> <title>基礎版本</title> <style> .pic1 { width: 400px; } .mask { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.7); } .previewImg { position: absolute; width: 80%; left: 50%; top: 200px; transform: translateX(-50%); } </style> </head> <body> <img class="pic1" src="./xtjj.jpg" alt=""> <script> const pic1 = document.querySelector(".pic1"); pic1.addEventListener("click", function () { // 創建蒙層 const mask = document.createElement("div") mask.classList.add("mask"); const pic1Clone = pic1.cloneNode(); pic1Clone.classList.add("previewImg"); // 將圖片和蒙層添加到頁面中 mask.appendChild(pic1Clone) document.body.appendChild(mask) mask.addEventListener("click", function () { document.body.removeChild(this) }) }) </script> </body> </html>
打開動畫
實現方式
- 點擊圖片
- 克隆原圖,計算原圖當前距離視窗的top與left的距離(用於確定克隆圖片的初始位置)
- 計算克隆圖片的初始位置以及其相關屬性
- 創建蒙層,並添加相關的定位,背景色屬性
- 使用
setTimeout
是為了觸發transition
,產生移動效果。 - 並且在
setTimeout
最開始將原圖進行隱藏,產生是原圖移動到屏幕中心的效果。使用visibility
屬性,避免引起頁面佈局變化。
- 為蒙層添加點擊事件
- 點擊蒙層後,刪除蒙層元素,實現關閉預覽功能
效果圖
代碼
<!DOCTYPE html> <html lang="en"> <head> <title>添加預覽動畫</title> <style> .pic { width: 400px; } .mask { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.7); transition: all .3s; } .previewImg { position: absolute; transform: translateX(-50%); transition: all .3s; } </style> </head> <body> <img class="pic" src="./xtjj.jpg" alt=""> <script> const pic = document.querySelector(".pic"); pic.addEventListener("click", function () { // 1,克隆元素 const pic2 = pic.cloneNode(); // 2,計算原圖距離視窗left,top的距離 picToTop = pic.getBoundingClientRect().x; picToLeft = pic.getBoundingClientRect().y; // 3,設置克隆圖片初始位置 pic2.style.position = "absolute"; pic2.style.left = `${picToLeft}px`; pic2.style.top = `${picToTop}px`; // 4,創建蒙層 const mask = document.createElement("div") mask.classList.add("mask"); // 5,將元素添加到body中 mask.appendChild(pic2) document.body.appendChild(mask) // 6,使用setTimeout是為了觸發`transition`,產生動畫 setTimeout(() => { // 7,隱藏原圖片 pic.style.visibility = "hidden"; // 8,設置預覽圖片展示寬度以及位置 pic2.style.width = "80%"; pic2.style.left = "50%"; pic2.style.top = `200px`; pic2.classList.add("previewImg"); }, 0); // 9,點擊蒙層關閉預覽 mask.addEventListener("click", function () { this.remove() }) }) </script> </body> </html>
關閉動畫
上一個步驟中,實現了點擊圖片,圖片流暢顯示的動畫。但是關閉的時候很突然,這次將實現關閉的流暢動畫。
實現方式
- 點擊圖片的時候獲取原圖的
寬度
,以及距離視窗left
,top
的距離 - 點擊蒙層的時候將克隆圖片的位置移動到原圖的位置(根據前面獲取的原圖位置)
- 當克隆圖片回到原圖的位置時,需要將原圖進行顯示。使用
visibility
屬性。 - 使用
setTimeout
的原因是觸發transition
,產生動畫效果。 - 使用300毫秒是因為
transition
設置的是300毫秒的過渡時間,為了能在克隆圖片會到原圖位置的時候,再顯示原圖,並刪除蒙層。
效果圖
代碼
查看下個步驟
滾動時取消預覽
實現方式
-
在點擊圖片的時候,存儲當前頁面滾動的距離:
lastPositon
-
監聽滾動事件,當滾動的距離減去
lastPositon
的值,大於100px
的時候,觸發矇層的點擊事件 -
蒙層收到點擊動作後,會執行取消預覽的一系列動作。
完整代碼
<!DOCTYPE html> <html lang="en"> <head> <title>滾動時取消預覽</title> <style> body { height: 1000px; } .pic { width: 400px; } .mask { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.7); transition: all .3s; } </style> </head> <body> <img class="pic" src="./xtjj.jpg" alt=""> <script> // 16,滾動超過100px。就取消預覽 window.onscroll = (e) => { if (Math.abs(window.pageYOffset - lastPositon) > 100) { document.querySelector(".mask")?.click(); } } // 14,預覽圖片前頁面滾動距離初始值 let lastPositon = 0; const pic = document.querySelector(".pic"); pic.addEventListener("click", function () { // 15,計算預覽圖片前頁面滾動距離 lastPositon = window.pageYOffset; // 1,克隆元素 const pic2 = pic.cloneNode(); // 2,計算原圖距離視窗left,top的距離 picToTop = pic.getBoundingClientRect().x; picToLeft = pic.getBoundingClientRect().y; // 11,計算原圖寬度 picWidth = pic.width; // 3,設置克隆圖片初始位置 pic2.style.position = "absolute"; pic2.style.left = `${picToLeft}px`; pic2.style.top = `${picToTop}px`; // 4,創建蒙層 const mask = document.createElement("div") mask.classList.add("mask"); // 5,將元素添加到body中 mask.appendChild(pic2) document.body.appendChild(mask) // 6,使用setTimeout是為了觸發`transition`,產生動畫 setTimeout(() => { // 7,隱藏原圖片 pic.style.visibility = "hidden"; // 8,設置預覽圖片展示寬度以及位置 pic2.style.position = "absolute"; pic2.style.transition = "all .3s"; pic2.style.transform = "translateX(-50%)"; pic2.style.width = "80%"; pic2.style.left = "50%"; pic2.style.top = `200px`; }, 0); // 9,點擊蒙層關閉預覽 mask.addEventListener("click", function () { // 10,預覽圖回到原圖位置 pic2.style.width = `${picWidth}px`; pic2.style.left = `${picToLeft}px`; pic2.style.top = `${picToTop}px`; pic2.style.transform = ""; // 12,顯示原圖 setTimeout(() => { pic.style.visibility = "visible"; // 13,刪除蒙層以及預覽圖 this.remove() }, 300); }) }) </script> </body> </html>