使用 Vanilla JavaScript 創建圖像縮放庫
在本教程中,我們將構建一個簡單的 JavaScript 庫,用於向圖像添加縮放懸停效果。我們將從頭開始製作整個庫,不依賴 jQuery 或任何其他外部依賴項。讓我們直接跳進去!
項目
您可以在許多購物網站上看到這種效果,包括 eBay 和亞馬遜等非常受歡迎的網站。它通常由一組小照片組成,這些照片可以放大並使用懸停放大鏡進行更詳細的檢查。
為了保持教程簡單,我們不會向庫中添加太多功能。它將僅包含一個 JavaScript 文件,以及一個可選的 CSS 文件,用於快速設置上述畫廊的樣式。
設計庫
在開始構建庫之前,讓我們先看看我們希望人們如何使用它。首先做出設計決策將使以後開發實際庫更容易。
由於我們正在製作一個畫廊插件,因此使用它的人將需要一些樣板 HTML。此標記將包含他們的圖像,一個空的 div
用於縮放效果,以及一些預定義的類以使庫正常工作。
<div id="my-gallery" class="vanilla-zoom"> <div class="sidebar"> <img src="images/image-1.jpg" class="small-preview"> <img src="images/image-2.jpg" class="small-preview"> <img src="images/image-3.jpg" class="small-preview"> </div> <div class="zoomed-image"></div> </div>
人們可以自由更改此佈局並添加任意數量的圖像。然而,重要的是,每張圖片都有 .small-preview
類,並且有一個帶有 .zoomed-image
的空 div 類。
該庫將主要由 JavaScript 驅動,但也有一些重要的 CSS 樣式需要設置。用戶可以將我們的 CSS 文件直接包含在他們的 HTML 中。
<link rel="stylesheet" href="vanilla-zoom/vanilla-zoom.css">
現在標記和样式都設置好了,剩下的就是包含庫並對其進行初始化。
<script src="vanilla-zoom/vanilla-zoom.js"></script> <script> vanillaZoom.init('#my-gallery'); </script>
包含庫的 .js 文件使 vanillaZoom
對象全局可用。該對像只有一種用於初始化插件的方法。它需要一個參數 - 我們畫廊的 id。這樣我們就可以在一個頁面上初始化多個獨立的畫廊。
開發庫
在構建前端 JavaScript 庫時,我們需要確保正確註冊它們的 API。有很多方法可以做到這一點,其中最簡單的可能是 Jordan Checkman 的這種方法。我們建議您閱讀他的完整博客文章,但簡而言之,它可以歸結為:
(function(window) { function define_library() { // Create the library object and all its properties and methods. var vanillaZoom = {}; vanillaZoom.init = function(galleryId) { // Our library's logic goes here. } return vanillaZoom; } // Add the vanillaZoom object to global scope if its not already defined. if(typeof(vanillaZoom) === 'undefined') { window.vanillaZoom = define_library(); } else{ console.log("Library already defined."); } })(window);
上面的代碼被包裝在一個自執行函數中。這樣當我們添加 vanilla-zoom.js
將文件添加到我們的項目中,該庫將自動註冊,vanillaZoom
對象及其所有方法都將提供給用戶。
我們的庫只有一種方法 - vanillaZoom.init(galleryId)
.它的工作是選擇畫廊 DOM 元素並向它們添加事件偵聽器。
首先,我們檢查是否已將正確的元素添加到 HTML 中並選擇它們。我們不能使用 jQuery,所以我們必須依賴原生 JavaScript 方法來處理 DOM。
var container = document.querySelector(el); if(!container) { console.error('Please specify the correct class of your gallery.'); return; } var firstSmallImage = container.querySelector('.small-preview'); var zoomedImage = container.querySelector('.zoomed-image'); if(!zoomedImage) { console.error('Please add a .zoomed-image element to your gallery.'); return; } if(!firstSmallImage) { console.error('Please add images with the .small-preview class to your gallery.'); return; } else { // Set the source of the zoomed image. zoomedImage.style.backgroundImage = 'url('+ firstSmallImage.src +')'; }
在上述代碼的最後一行,我們獲取其中一張預覽圖像的圖像源並將其設置為可縮放元素的背景。這發生在 vanillaZoom.init(galleryId)
被調用,確保我們的畫廊不會空著。
單擊其中一個預覽時,我們也會這樣做。這允許用戶選擇他們想要放大的圖像。
container.addEventListener("click", function (event) { var elem = event.target; if (elem.classList.contains("small-preview")) { zoomedImage.style.backgroundImage = 'url('+ elem.src +')'; } });
放大鏡元素附有幾個事件監聽器。第一個在光標進入元素時激活,增加背景圖像的大小,從而創建縮放效果。
zoomedImage.addEventListener('mouseenter', function(e) { this.style.backgroundSize = "250%"; }, false);
由於圖像現在非常大,它不適合容器,只有一部分可見。我們希望用戶能夠選擇放大圖像的哪個部分,因此我們添加了一個 mousemove 監聽器來改變背景位置。
zoomedImage.addEventListener('mousemove', function(e) { // getBoundingClientReact gives us various information about the position of the element. var dimentions = this.getBoundingClientRect(); // Calculate the position of the cursor inside the element (in pixels). var x = e.clientX - dimentions.left; var y = e.clientY - dimentions.top; // Calculate the position of the cursor as a percentage of the total size of the element. var xpercent = Math.round(100 / (dimentions.width / x)); var ypercent = Math.round(100 / (dimentions.height / y)); // Update the background position of the image. this.style.backgroundPosition = xpercent+'% ' + ypercent+'%'; }, false);
當光標離開放大的圖像時,我們希望它恢復正常。這很容易通過將背景大小返回到 cover
來完成 和 center
的背景位置 .
zoomedImage.addEventListener('mouseleave', function(e) { this.style.backgroundSize = "cover"; this.style.backgroundPosition = "center"; }, false);
至此,我們就完成了!
瀏覽器支持
該庫應該適用於所有現代桌面瀏覽器,儘管某些 flexbox CSS 可能無法在舊版 IE 上正確顯示。
可悲的是,縮放效果不能很好地轉化為觸摸設備。由於這一點和有限的屏幕空間,最好以另一種方式呈現您的圖像以供移動設備使用。在我們的 CSS 中,我們只是隱藏了縮放元素並垂直列出了圖像,但您可以嘗試其他解決方案,例如輪播。
結論
您可以從下載獲取本文的完整源代碼以及演示代碼(圖片由 Burst 提供) 靠近頁面頂部的按鈕。您可以在所有項目中自由使用該庫,無論是商業項目還是個人項目(我們的許可證)。編碼愉快!