簡單圖片懶加載的實現

爲何須要圖片懶加載

通常在開發商城列表頁,或者相冊的時候會有不少的圖片請求,若是同時所有請求對服務器端的壓力會比較大(不是隻有你一我的),因此就有了圖片的懶加載,懶加載意思就是隻加載可視區域的圖片git

怎麼實現

大概思路是這樣子的:github

1.滾動條的高度加上可視區域的高度 > 目標對象距離頂部的高度就意味在可視範圍內。
window.scrollY + window.innerHeight > img.offsetTop
2.img的src屬性使用一個空值,自定義一個屬性data-src綁定真實圖片url
3.當處於可視範圍內的時候src綁定data-src的屬性值
複製代碼

最開始版本:

// 基礎版本當在可視範圍內的時候就展現圖片
class lazyLoad {
    constructor () {
        const imgs = document.getElementsByTagName('img')
        // 獲取到的是類數組,須要轉換成數組類型,以便使用數組方法
        this.imgs = Array.from([...imgs])
        this.init()
    }

    // 方法一計算高度判斷是否在視口內部
    viewImage () {
         let height = window.scrollY + window.innerHeight
         this.imgs.forEach(img => {
             if (img.offsetTop < height) {
                 const realURL = img.getAttribute('data-src')
                 // 版本一 爲了表現明顯點加個定時器
                setTimeout(() => {
                    img.src = realURL
                }, 200)
             } 
         })
    }

    init () {
        let that = this
        // 版本一
        window.onscroll = function () {
            that.viewImage()
        }
    }
}
new lazyLoad()
複製代碼

window綁定scroll事件,因爲scoll事件觸發評率極高,影響瀏覽器的性能,因此加一個節流300ms觸發一次數組

節流版

// 簡易版節流
function throttle(func, wait) {
    var pre = 0
    return function() {
        var now = new Date()
        var context = this
        if (now - pre > wait) {
            func.apply(context)
            pre = now
        }
    }
}
init () {
    let that = this
    // 版本一
    window.onscroll = throttle(function () {
        that.viewImage()
    }, 300)
}
複製代碼

IntersectionObserver版本

IntersectionObserver API能自動監聽目標是否在可視區域內,這樣子就不要判斷高度了;瀏覽器

class lazyLoad {
    constructor () {
        const imgs = document.getElementsByTagName('img')
        this.imgs = imgs
        this.init()
    }
    viewImage () {
        // start observing
        for (let img of this.imgs) {
            const intersectionObserver = new IntersectionObserver(function(entries) {
                // If intersectionRatio is 0, the target is out of view
                // and we do not need to do anything.
                for(let entry of entries) {
                    if (entry.intersectionRatio <= 0) return
                    else {
                        const img = entry.target
                        const realURL = img.dataset.src
                        img.src = realURL
                    }
                }
            });
            // 開始監聽
            intersectionObserver.observe(img)
        }
    }
    init () {
        this.viewImage()
    }
}

new lazyLoad()
複製代碼

IntersectionObserver的介紹,能夠查看文檔服務器

最終版本

爲了兼容低版本瀏覽器因此要結合兩個版本:app

// 基礎版本當在可視範圍內的時候就展現圖片
class lazyLoad {
    constructor () {
        const imgs = document.getElementsByTagName('img')
        // this.imgs = Array.from([...imgs])
        this.imgs = imgs
        this.init()
    }

    // 方法一計算高度判斷是否在視口內部
    viewImage2 () {
        let windowHeight = window.scrollY + window.innerHeight
        this.imgs.forEach(img => {
            if (img.offsetTop < windowHeight) {
                const realURL = img.getAttribute('data-src')
                 // 版本一 爲了表現明顯點加個定時器
                setTimeout(() => {
                    img.src = realURL
                }, 200)
             } 
        })
    }

    // 方法二利用API判斷是否在視口內
    viewImage () {
        // start observing
        for (let img of this.imgs) {
            const intersectionObserver = new IntersectionObserver(function(entries) {
                // If intersectionRatio is 0, the target is out of view
                // and we do not need to do anything.
                for(let entry of entries) {
                    if (entry.intersectionRatio <= 0) return
                    else {
                        const img = entry.target
                        const realURL = img.dataset.src
                        img.src = realURL
                    }
                }
            });
            intersectionObserver.observe(img)
        }
    }
    init () {
        let that = this
        // 判斷是否支持IntersectionObserver
        if ('IntersectionObserver' in window) {
            that.viewImage()
        } else {
            window.onscroll = throttle(function () {
                that.viewImage2()
            }, 500)
        }
    }
}

new lazyLoad()

複製代碼

到此一個簡單版的圖片懶加載就完成了。性能

動動手才能變強吧。ui

源碼地址 github.com/wanghao1993…this

相關文章
相關標籤/搜索