摘要:什么時候用懶加載當頁面中需要一次性載入很多圖片的時候,往往都是需要用懶加載的。屬性是一個必需的屬性,它規定在圖像無法顯示時的替代文本。假設來表示圖片到可視區域頂部距離并設來表示可視區域的高度。
懶加載
什么是懶加載
懶加載其實就是延遲加載,是一種對網頁性能優化的方式,比如當訪問一個頁面的時候,優先顯示可視區域的圖片而不一次性加載所有圖片,當需要顯示的時候再發送圖片請求,避免打開網頁時加載過多資源。
什么時候用懶加載
當頁面中需要一次性載入很多圖片的時候,往往都是需要用懶加載的。
懶加載原理
我們都知道HTML中的 標簽是代表文檔中的一個圖像。。說了個廢話。。
標簽有一個屬性是 src,用來表示圖像的URL,當這個屬性的值不為空時,瀏覽器就會根據這個值發送請求。如果沒有 src屬性,就不會發送請求。
嗯?貌似這點可以利用一下?
我先不設置 src,需要的時候再設置?
nice,就是這樣。
我們先不給 設置 src,把圖片真正的URL放在另一個屬性 data-src中,在需要的時候也就是圖片進入可視區域的之前,將URL取出放到 src中。
實現
HTML結構
仔細觀察一下, 標簽此時是沒有 src屬性的,只有 alt和 data-src屬性。
alt 屬性是一個必需的屬性,它規定在圖像無法顯示時的替代文本。 data-* 全局屬性:構成一類名稱為自定義數據屬性的屬性,可以通過 HTMLElement.dataset來訪問。
如何判斷元素是否在可視區域
方法一
網上看到好多這種方法,稍微記錄一下。
通過 document.documentElement.clientHeight獲取屏幕可視窗口高度
通過 document.documentElement.scrollTop獲取瀏覽器窗口頂部與文檔頂部之間的距離,也就是滾動條滾動的距離
通過 element.offsetTop獲取元素相對于文檔頂部的距離
然后判斷②-③<①是否成立,如果成立,元素就在可視區域內。
方法二(推薦)
通過 getBoundingClientRect()方法來獲取元素的大小以及位置,MDN上是這樣描述的:
The Element.getBoundingClientRect() method returns the size of an element and its position relative to the viewport.
這個方法返回一個名為 ClientRect的 DOMRect對象,包含了 top、 right、 botton、 left、 width、 height這些值。
MDN上有這樣一張圖:
可以看出返回的元素位置是相對于左上角而言的,而不是邊距。
我們思考一下,什么情況下圖片進入可視區域。
假設 constbound=el.getBoundingClientRect();來表示圖片到可視區域頂部距離; 并設 constclientHeight=window.innerHeight;來表示可視區域的高度。
隨著滾動條的向下滾動, bound.top會越來越小,也就是圖片到可視區域頂部的距離越來越小,當 bound.top===clientHeight時,圖片的上沿應該是位于可視區域下沿的位置的臨界點,再滾動一點點,圖片就會進入可視區域。
也就是說,在 bound.top<=clientHeight時,圖片是在可視區域內的。
我們這樣判斷:
function isInSight(el) {
const bound = el.getBoundingClientRect(); const clientHeight = window.innerHeight; //如果只考慮向下滾動加載 //const clientWidth = window.innerWeight; return bound.top <= clientHeight + 100;
}
這里有個+100是為了提前加載。
加載圖片
頁面打開時需要對所有圖片進行檢查,是否在可視區域內,如果是就加載。
function checkImgs() {
const imgs = document.querySelectorAll(".my-photo"); Array.from(imgs).forEach(el => { if(isInSight(el)) { loadImg(el); } })
}
function loadImg(el) {
if(!el.src) { const source = el.dataset.src; el.src = source; }
}
這里應該是有一個優化的地方,設一個標識符標識已經加載圖片的index,當滾動條滾動時就不需要遍歷所有的圖片,只需要遍歷未加載的圖片即可。
函數節流
在類似于滾動條滾動等頻繁的DOM操作時,總會提到“函數節流、函數去抖”。
所謂的函數節流,也就是讓一個函數不要執行的太頻繁,減少一些過快的調用來節流。
基本步驟:
獲取第一次觸發事件的時間戳
獲取第二次觸發事件的時間戳
時間差如果大于某個閾值就執行事件,然后重置第一個時間
function throttle(fn, mustRun = 500) {
const timer = null; let previous = null; return function() { const now = new Date(); const context = this; const args = arguments; if(!previous) { previous = now; } const remaining = now - previous; if(mustRun && remaining >= mustRun) { fn.apply(context, args); previous = now; } }
}
這里的 mustRun就是調用函數的時間間隔,無論多么頻繁的調用 fn,只有 remaining>=mustRun時 fn才能被執行。
實驗
頁面打開時
可以看出此時僅僅是加載了img1和img2,其它的img都沒發送請求,看看此時的瀏覽器
第一張圖片是完整的呈現了,第二張圖片剛進入可視區域,后面的就看不到了~
頁面滾動時
當我向下滾動,此時瀏覽器是這樣
此時第二張圖片完全顯示了,而第三張圖片顯示了一點點,這時候我們看看請求情況
img3的請求發出來,而后面的請求還是沒發出~
全部載入時
當滾動條滾到最底下時,全部請求都應該是發出的,如圖
更新
方法三 IntersectionObserver
經大佬提醒,發現了這個方法
先附上鏈接:
jjc大大:
https://github.com/justjavac/...
阮一峰大大:
http://www.ruanyifeng.com/blo...
API Sketch for Intersection Observers:
https://github.com/WICG/Inter...
IntersectionObserver可以自動觀察元素是否在視口內。
var io = new IntersectionObserver(callback, option);
// 開始觀察
io.observe(document.getElementById("example"));
// 停止觀察
io.unobserve(element);
// 關閉觀察器
io.disconnect();
callback的參數是一個數組,每個數組都是一個 IntersectionObserverEntry對象,包括以下屬性:
屬性 描述
time 可見性發生變化的時間,單位為毫秒
rootBounds 與getBoundingClientRect()方法的返回值一樣
boundingClientRect 目標元素的矩形區域的信息
intersectionRect 目標元素與視口(或根元素)的交叉區域的信息
intersectionRatio 目標元素的可見比例,即intersectionRect占boundingClientRect的比例,完全可見時為1,完全不可見時小于等于0
target 被觀察的目標元素,是一個 DOM 節點對象
我們需要用到 intersectionRatio來判斷是否在可視區域內,當 intersectionRatio>0&&intersectionRatio<=1即在可視區域內。
代碼
function checkImgs() {
const imgs = Array.from(document.querySelectorAll(".my-photo")); imgs.forEach(item => io.observe(item));
}
function loadImg(el) {
if(!el.src) { const source = el.dataset.src; el.src = source; }
}
const io = new IntersectionObserver(ioes => {
ioes.forEach(ioe => { const el = ioe.target; const intersectionRatio = ioe.intersectionRatio; if(intersectionRatio > 0 && intersectionRatio <= 1) { loadImg(el); } el.onload = el.onerror = () => io.unobserve(el); });
});
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/103616.html
摘要:原文地址原生實現最簡單的圖片懶加載歡迎。什么時候用懶加載當頁面中需要一次性載入很多圖片的時候,往往都是需要用懶加載的。屬性是一個必需的屬性,它規定在圖像無法顯示時的替代文本。假設來表示圖片到可視區域頂部距離并設來表示可視區域的高度。 原文地址:原生JS實現最簡單的圖片懶加載 歡迎star。 如果有錯誤的地方歡迎指正。 Demo地址:http://axuebin.com/lazyloa...
摘要:前言圖片懶加載也是比較常見的一種性能優化的方法,最近在用做一個新聞列表的客戶端時也用到了,這里就簡單介紹下實現原理和部分代碼。,當前圖片距離頂部的距離。 前言 ?圖片懶加載也是比較常見的一種性能優化的方法,最近在用vue做一個新聞列表的客戶端時也用到了,這里就簡單介紹下實現原理和部分代碼。 實現原理 ?加載頁面的時候,圖片一直都是流量大頭,針對圖片的性能方法也挺多的比如base64、...
摘要:前言圖片懶加載也是比較常見的一種性能優化的方法,最近在用做一個新聞列表的客戶端時也用到了,這里就簡單介紹下實現原理和部分代碼。,當前圖片距離頂部的距離。 前言 ?圖片懶加載也是比較常見的一種性能優化的方法,最近在用vue做一個新聞列表的客戶端時也用到了,這里就簡單介紹下實現原理和部分代碼。 實現原理 ?加載頁面的時候,圖片一直都是流量大頭,針對圖片的性能方法也挺多的比如base64、...
摘要:方法返回元素的大小及其相對于視口的位置。對象包含了一組用于描述邊框的只讀屬性和,單位為像素。這樣就實現了圖片的懶加載的簡單實現,當然還可以對進行優化等操作,這里不做過多闡述了。演示地址圖片的懶加載 思路 首先,什么是懶加載,從字面意思就可以簡單的理解為不到用時就不去加載,對于頁面中的元素,我們可以這樣理解:只有當滾動頁面內容使得本元素進入到瀏覽器視窗時(或者稍微提前,需給定提前量),我...
摘要:前言最近在整理基礎知識,接觸到了幾個常用的頁面特效,其中覺得用原生實現瀑布流的案例十分有趣,于是與大家分享一下。瀑布流瀑布流,又稱瀑布流式布局。通過定位的方式是我們實現瀑布流的最基本的原理,只要我們動態的設置它的值值,就能讓它排列。 showImg(https://segmentfault.com/img/remote/1460000012621941?w=1052&h=542); 前...
閱讀 2927·2021-11-24 09:39
閱讀 3610·2021-11-22 13:54
閱讀 3414·2021-11-16 11:45
閱讀 2439·2021-09-09 09:33
閱讀 3199·2019-08-30 15:55
閱讀 1296·2019-08-29 15:40
閱讀 924·2019-08-29 15:19
閱讀 3400·2019-08-29 15:14