摘要:最后,我們必須調用函數來檢查所有的漸進式圖片容器在首次運行時是否在頁面上可見。我們還必須在滾動頁面或調整瀏覽器大小時調用函數,在一些舊的瀏覽器主要指可以非常迅速地對這些事件作出回應,所以我們需要限制回調,以確保它不能在毫秒內被再一次調用。
你可以在Facebook和Medium上遇到過漸進式圖片,當頁面滾動到視圖時,模糊的低分辨率圖像會被清晰的全分辨率版本替換。
預覽圖片非常?。ㄒ苍S是20px寬的高壓縮JPEG格式),該文件可以小于300字節,并立即出現快速加載的模糊輪廓,當需要的時候,會通過延遲加載的形式加載真實圖像。
漸進式圖像非常偉大,但是目前的解決方案比較復雜。幸運的是,我們可以用HTML5/CSS3/JavaScript構建一個示例,示例代碼:
快速輕量級——只需463字節的CSS和1007字節的JavaScript(經壓縮)
支持響應式圖片加載更大或更高分辨率(Retina)屏幕的替代版本
沒有依賴——可與任何框架工作
兼容所有現代瀏覽器(IE10+)
在舊版瀏覽器中,或是當JavaScript/圖片加載失敗時,會漸進增強
易于使用
我們的演示和GitHub代碼這是我們的demo示例
Download the code from GitHub
我們會以一些基礎HTML來實現漸進式圖片:
此處:
full.jpg 是清晰的大分辨率圖片,地址在href中
tiny.jpg 是輕量的預覽圖片
我們已經有一個小型工作系統了,沒有任何的JavaScript(也許在舊的瀏覽器中會失效),用戶可以通過點擊預覽完整的圖片。
兩個圖片必須有相同的寬高比,例如,如果full.jpg是800*200,則其最終的寬高比是4:1,那么tiny.jpg可以是4:1,但是不能使用30px的寬度,因為那樣高度將會是一個分數而不是7.5px。
注意鏈接和預覽圖片上使用到的classes,這些會被我們運用到JavaScript中。
內聯或外聯圖片預覽圖片可以以data URL的形式內聯,例如:
內聯圖片會立即顯示,需要較少的HTTP請求,并避免額外的頁面回流,但是:
他需要更多資源來添加或更改內聯圖片(雖然構建時候, 可以借助如Gulp的幫助)
base-64編碼效率較低,通常比二進制數據大30%(盡管這被額外的HTTP請求頭抵消了)
內聯圖片無法緩存在本地,它們只能在HTML頁面中緩存,如果不提出相同的請求,它們不能在另一個頁面使用
HTTP/2減少了對內聯圖片的需求
CSS比較實用的是:如果內聯圖片只在單個頁面使用,并且所需代碼量很?。ㄈ鏤RL比較短),內聯圖片是一個不錯的選擇。
我們先來定義container樣式:
a.progressive { position: relative; display: block; overflow: hidden; outline: none; }
這是設置container容器的布局屬性,如果有需要,link可以應用其他類和樣式設置尺寸或位置。
你可以考慮使用精確的尺寸或使用padding-top來強制實現固有的寬高比,這能確保在容器進行尺寸調整前避免圖片加載的負載和回流,不過這要計算每個圖像的大小和寬高比。我選擇比較簡單的方式:
預覽和大圖必須具有相同的寬高比(見上文)
預覽圖片將幾乎立即定義容器的高度,因為它是內聯的,或是快速加載的
再次提示:如果你在一個包含大量圖片的網頁上,定義了容器固定的寬度和高度,效果會更好,例如一個圖庫(所有的圖片都可能具有相同的寬高比)。
當完整的大圖加載完成并且點擊事件停止時,容器上的"replace"類將被刪除,因此,我們可以刪除標準鏈接指針。
a.progressive:not(.replace) { cursor: default; }
容器中的預覽圖和大圖根據容器的寬度調整大?。?/p>
a.progressive img { display: block; width: 100%; max-width: none; height: auto; border: 0 none; }
注意height:auto是必須的,IE10/11可能會在計算圖像高度的時候出錯。
預覽圖像使用2vw的長度模糊,確保模糊后看起來有相似的輪廓,而與頁面大小無關。在container中應用overflow: hidden可為容器提供一個硬邊緣。它也縮放1.05倍,防止通過圖片的模糊外邊緣看到圖片的背景顏色。這表示我們可以使用令人愉快的縮放效果來顯示完整的圖像。
a.progressive img.preview { filter: blur(2vw); transform: scale(1.05); }
最后,我們定義圖片完整顯示時候的樣式和動畫:
a.progressive img.reveal { position: absolute; left: 0; top: 0; will-change: transform, opacity; animation: reveal 1s ease-out; } @keyframes reveal { 0% {transform: scale(1.05); opacity: 0;} 100% {transform: scale(1); opacity: 1;} }
大圖位于預覽圖上方,在1秒內,不透明度從0增加到1,刻度從1.05變為1。你可以根據自己的需要增加其他的轉換/過濾效果。
JavaScript我們遵循的是漸進增強模式,所以JavaScript代碼最初會向頁面添加load事件監聽器之前檢查所需瀏覽器的API是否可用。
// progressive-image.js if (window.addEventListener && window.requestAnimationFrame && document.getElementsByClassName) window.addEventListener("load", function() {
當頁面和所有資源加載完成時,將觸發load事件。我們不希望大型圖片在基本資源(如字體、CSS、JavaScript和預覽圖片)加載完成之前加載(這可能發生:我們使用DOMContentLoaded事件——當DOM準備就緒時觸發的事件)。
接下來,我們獲取獲取類名為progressive和replace的所有圖像容器元素:
var pItem = document.getElementsByClassName("progressive replace"), timer;
getElementsByClassName()返回一個活動的類數組HTMLCollection,匹配到的元素將從頁面中添加或刪除。它的好處是很快就會顯示出來。
接下來,我么將定義一個inView()函數,該函數通過其getBoundingClientRect()方法和window.pageYOffset垂直滾動位置進行比較,從而確定容器是否在視圖內。
// image in view? function inView() { var wT = window.pageYOffset, wB = wT + window.innerHeight, cRect, pT, pB, p = 0; while (p < pItem.length) { cRect = pItem[p].getBoundingClientRect(); pT = wT + cRect.top; pB = pT + cRect.height; if (wT < pB && wB > pT) { loadFullImage(pItem[p]); pItem[p].classList.remove("replace"); } else p++; } }
當容器在視圖中時,它的節點會被傳遞到loadFullImage()函數內,并且replace類會被刪除(會立即從pItem HTMLCollection中刪除節點,因此容器不會被再次重新處理)。
loadFullImage()函數創建了一個新的HTML Image()對象,并根據需要設置其值,即將容器的href的值復制到src屬性中,并應用一個reveal類。
// replace with full image function loadFullImage(item) { if (!item || !item.href) return; // load image var img = new Image(); if (item.dataset) { img.srcset = item.dataset.srcset || ""; img.sizes = item.dataset.sizes || ""; } img.src = item.href; img.className = "reveal"; if (img.complete) addImg(); else img.onload = addImg;
加載圖片后調用內部的addImg函數:
// replace image function addImg() { // disable click item.addEventListener("click", function(e) { e.preventDefault(); }, false); // add full image item.appendChild(img).addEventListener("animationend", function(e) { // remove preview image var pImg = item.querySelector && item.querySelector("img.preview"); if (pImg) { e.target.alt = pImg.alt || ""; item.removeChild(pImg); e.target.classList.remove("reveal"); } }); } }
注意:
禁用容器上的點擊事件
將圖像附加到開始淡出淡入/縮放動畫的頁面
使用animationend監聽器等待動畫結束,然后復制alt
內容。刪除預覽圖片節點,并從完整圖片中刪除reveal類。這一步有助于提高性能,并且防止在調整Edge瀏覽器大小時出現一些奇怪的剪切問題。
最后,我們必須調用inView()函數來檢查所有的漸進式圖片容器在首次運行時是否在頁面上可見。
inView();
我們還必須在滾動頁面或調整瀏覽器大小時調用函數,在一些舊的瀏覽器(主要指IE)可以非常迅速地對這些事件作出回應,所以我們需要限制回調,以確保它不能在300毫秒內被再一次調用。
window.addEventListener("scroll", scroller, false); window.addEventListener("resize", scroller, false); function scroller(e) { timer = timer || setTimeout(function() { timer = null; requestAnimationFrame(inView); }, 300); }
響應式圖片注意,對requestAnimationFrame的調用,它將在下一次重繪inView函數。
HTML 中 image的srcset和sizes屬性定義了不同大小和分辨率的多個圖像,瀏覽器可以為設備選擇最合適的版本。
上面的代碼支持這個功能——添加data-srcset和data-sizes屬性到link容器,例如:
加載完成后,完整的圖片代碼將是:
當視圖窗口寬度為800px或更高時,現代瀏覽器將加載large.jpg,舊版瀏覽器和視圖窗口較小的瀏覽器會加載small.jpg。詳細信息,請查閱 How to Build Responsive Images with srcset
使用筆記我會保持代碼的輕量性,并且可以隨時使用和易于改進,有待優化的地方有:
水平方向的滾動檢查。目前只檢查垂直方向的滾動
動態添加漸進式圖像。使用JavaScript動態添加的漸進式圖像只有在發生滾動或調整大小事件發生時才會被替換
Firefox性能。瀏覽器在替換大圖片時可能會遇到困難(你也許可以看到明顯的閃爍)
作者:Craig Buckler
原文:How to Build Your Own Progressive Image Loader
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/111767.html
摘要:入口文件打包出口地址在中可以配置我們的地址這里你要有一個七牛云的賬戶。特別像是七牛云這樣擁有圖片處理引擎的服務商,我們還可以通過來處理上傳至的圖片。 本項目源碼均可在 這里 找到。 之前公司的官網項目靜態文件都是放在靜態服務器中,這其中的弊端就不贅述了。簡單說一下 CDN 的好處: CDN 可以解決因分布、帶寬、服務器性能帶來的訪問延遲問題,適用于站點加速、點播、直播等場景。使用戶可就...
摘要:點擊直達前文譯一個小時搭建一個全棧應用框架上如果沒有,但還是要繼續學習本教程,可以到我的頁面下載代碼。從服務器返回隨機語言的每當我們與服務器上的端點進行通話時,為了能夠請求一個隨機的歐洲語言,必須更改文件中的功能。 翻譯:瘋狂的技術宅原文標題:Creating a full-stack web application with Python, NPM, Webpack and Reac...
摘要:點擊直達前文譯一個小時搭建一個全棧應用框架上如果沒有,但還是要繼續學習本教程,可以到我的頁面下載代碼。從服務器返回隨機語言的每當我們與服務器上的端點進行通話時,為了能夠請求一個隨機的歐洲語言,必須更改文件中的功能。 翻譯:瘋狂的技術宅原文標題:Creating a full-stack web application with Python, NPM, Webpack and Reac...
摘要:現在來做一個的入口讓我們在文件里進行的配置。如果想要顯示它們,我們可以在運行的時候使用你還可以使用,在改變代碼的時候自動進行打包。新建文件,里面是一段,告訴使用進行預處理。 本文譯自:Webpack your bags這篇文章由入門到深入的介紹了webpack的功能和使用技巧,真心值得一看。 由于我英語水平有限,而且很少翻譯文章,所以文中的一些語句在翻譯時做了類似語義的轉換,望諒解。...
閱讀 581·2021-11-22 14:45
閱讀 3070·2021-10-15 09:41
閱讀 1554·2021-10-11 10:58
閱讀 2796·2021-09-04 16:45
閱讀 2604·2021-09-03 10:45
閱讀 3238·2019-08-30 15:53
閱讀 1221·2019-08-29 12:28
閱讀 2133·2019-08-29 12:14