简单图片懒加载的实现

为何须要图片懒加载

通常在开发商城列表页,或者相册的时候会有不少的图片请求,若是同时所有请求对服务器端的压力会比较大(不是只有你一我的),因此就有了图片的懒加载,懒加载意思就是只加载可视区域的图片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

相关文章
相关标签/搜索