爲何要使用圖片懶加載?css
當咱們作一個商城項目,那麼首頁會加載不可預計的商品數量,也就是圖片;有的圖片甚至能夠達到600KB-900KB,當圖片數量不少的時候,首頁就會加載很慢,會直接影響到用戶的體驗。html
像相似這種圖片過多的頁面,咱們能夠經過圖片懶加載Lazyload對圖片進行處理,減輕頁面的加載負擔。圖片懶加載的思路是將頁面內的圖片未出如今瀏覽器的可視區域的圖片先不作加載,等到圖片滾動到瀏覽器的可視區域後,再去作加載。這樣即提升首頁加載性能,也提升了用戶的體驗感。瀏覽器
先將圖片地址使用 data-src
屬性保存起來,src
屬性就用默認的;bash
<img data-src="https://img.png" src="placeholder.png" />
複製代碼
檢測圖片是否出如今瀏覽器的可視區域,這裏介紹兩種作法:異步
plan A性能
利用滾動事件 scroll
監聽窗口元素ui
window.addEventLister('scroll', function(){
// 事件監聽
})
window.removeEventLister('scroll', function() {
// 事件卸載
})
複製代碼
頁面加載時判斷圖片的offsetTop
是否出如今瀏覽器的可視區域,爲true 時把img
標籤data-src
屬性賦值給src
,這樣就達到了圖片懶加載需求。spa
plan Bcode
使用 Intersection Observercdn
Intersection Observer API提供了一種異步觀察目標元素與祖先元素或頂級文檔viewport的交集中的變化的方法。
這裏就不作詳細的概述了, Intersection Observer 點擊查看API>
let options = {
root: document.querySelector('#scrollEl'),
rootMargin: '0px',
threshold: 1.0
}
let observer = new IntersectionObserver(callback, options)
function callback (entries, observer) {
entries.forEach(function(entry) {
// ....
})
}
複製代碼
plan A 使用滾動事件 scroll 實現
HTML
<div class="doc">
<img class="img" data-src="https://img.png" src="placeholder.png" />
<img class="img" data-src="https://img.png" src="placeholder.png" />
<img class="img" data-src="https://img.png" src="placeholder.png" />
<img class="img" data-src="https://img.png" src="placeholder.png" />
<img class="img" data-src="https://img.png" src="placeholder.png" />
<img class="img" data-src="https://img.png" src="placeholder.png" />
<img class="img" data-src="https://img.png" src="placeholder.png" />
<img class="img" data-src="https://img.png" src="placeholder.png" />
<img class="img" data-src="https://img.png" src="placeholder.png" />
</div>
複製代碼
css
.doc { width: 100%; }
img { width: 100%; }
複製代碼
js
window.onload = function () {
// 圖片集合
let imgs = document.querySelectorAll('.img')
function init() {
imgs.forEach(function(item) {
// 瀏覽器窗口top位置
let windowTop = document.documentElement.clientTop
// 瀏覽器窗口高度
let windowHeight = document.documentElement.clienHeight
// 圖片距離窗口的值
let imgsTop = item.getBoundingClientRect().top
// 詳細說明請看大屏幕 ^-^
if (imgsTop - windowTop <= windowHeight) {
// 獲取保存到data-src 的圖片地址
let src = item.getAttribute('data-src')
// 再設置他的src值
item.setAttrbute('src', src)
}
})
}
// 初始化
init()
// 滾動監聽
window.addEventerListener('scroll', init)
}
複製代碼
第一種方法已經實現完成, 有什麼不對的地方,請各位大神指正 ^-^
複製代碼
plan B 使用 Intersection Observer
PS: 判斷元素是否發生交集點實現
window.onload = function() {
// 圖片集合
let imgs = document.querySelectorAll('.img')
const option = {
// root 目標元素的父級元素。若是未指定或者爲null,則默認爲瀏覽器視窗。
// root: '',
rootMargin: '0px',
threshold: 1.0
}
function init(target) {
// 有圖爲證 ^-^
const intersectionObserver = new IntersectionObserver(
function(entries, observer){
entries.forEach(function(entry){
// 當root 元素與目標元素相交 isIntersectiong 爲true,
if (entry.isIntersectiong) {
// 獲取保存到data-src 的圖片地址
const src = entry.getAttribute('data-src')
// 再設置他的src值
entry.setAttrbute('src', src)
// 斷開鏈接
observer.disconnect()
}
}
}, option)
intersectionObserver.observer(target)
}
imgs.forEact(function(item) {
init(item)
}
}
複製代碼
^-^ 歡迎大神吐槽🙈