有時候頁面中會有不少圖片,一個圖片就意味着一個http請求,一個js文件幾十k,一張圖片就多是幾M,過多的圖片須要很長的加載時間,等圖片加載完成,早就人走茶涼,圖片懶加載對提高用戶體驗有着顯著的效果瀏覽器
當圖片不在可視區域內時,統一設置img
的src
爲指定圖片src='default.png'
,添加data-src
(自定義屬性)屬性指向真實圖片url
bash
<img src='default.png' data-src='httt://www.xxx.com/images/001.jpg'>
複製代碼
監聽scroll事件,當圖片出如今可視區時,提取data-src
的值並賦給src
,加載真正圖片app
let img = document.getElementsByTagName('img')
//設置每次遍歷的起始圖片,防止重複加載
let n = 0
//加載可視區域圖片
lazyLoad()
window.onscroll = lazyLoad
function lazyLoad() {
let seeHeight = document.documentElement.clientHeight
let scrollHeight = document.body.scrollHeight
for (let i = n; i<img.length;i++) {
if(img[i].src === 'default.png'){
if(img[i].offsetHeight < seeHeight + scrollHeight){
img[i].setAttribute('src',img[i].getAttribute('data-src'))
n++
}
}
}
}
複製代碼
還沒完,lazyLode
與scorll
事件綁定會致使高頻觸發,這隻會增長瀏覽器的壓力,違背了咱們的初衷,因此咱們須要限制事件頻率,改良代碼以下函數
let img = document.getElementsByTagName('img')
//設置每次遍歷的起始圖片,防止重複加載
let n = 0
//加載可視區域圖片
lazyLoad()
function lazyLoad() {
let seeHeight = document.documentElement.clientHeight
let scrollHeight = document.body.scrollHeight
for (let i = n; i<img.length;i++) {
if(img[i].src === 'default.png'){
if(img[i].offsetHeight < seeHeight + scrollHeight){
img[i].setAttribute('src',img[i].getAttribute('data-src'))
n++
}
}
}
}
//防抖
function debounce(fn,wait) {
let timeout = null
return function(){
let context = this
let args = arguments
clearTimeout(timeout)
timeout = setTimeout( function(){
fn.apply(context,args)
},wait)
}
}
window.addEventListener('scroll',debounce(lazyLoad,800),true)
複製代碼
debounce
函數限制了lazyLoad
的觸發頻率,800ms等待時間內scroll時間再次觸發則重置時間,術語叫防抖。這就完了?nonono!假設咱們把wait
設的大點,2s,若是用戶一直滑動滾動條,時間不斷被重置,形成的效果是lazyLoad
一直不被執行,圖片加載不出來,這是不能接受的,因此咱們須要設置一個時間,超過該時間lazyLoad
必須執行一次,術語叫節流
,代碼以下ui
let img = document.getElementsByTagName('img')
//設置每次遍歷的起始圖片,防止重複加載
let n = 0
//加載可視區域圖片
lazyLoad()
function lazyLoad() {
let seeHeight = document.documentElement.clientHeight
let scrollHeight = document.body.scrollHeight
for (let i = n; i<img.length;i++) {
if(img[i].src === 'default.png'){
if(img[i].offsetHeight < seeHeight + scrollHeight){
img[i].setAttribute('src',img[i].getAttribute('data-src'))
n++
}
}
}
}
//節流
function throttle(fn,wait,mustTime){
let timeout = null
let startTime = new Date()
let curTime
return function(){
let context = this
let args = arguments
curTime = new Date()
if( (curTime - startTime) >= mustTime){
startTime = curTime
fn.apply(context,args)
clearTimeout(timeout)
}else{
clearTimeout(timeout)
timeout = setTimeout( function(){
fn.apply(context,args)
startTime = new Date()
},wait)
}
}
}
window.addEventListener('scroll',throttle( lazyLoad,2000,3000))
複製代碼