前端页面图片懒加载方式

方式一: 分批加载图片

在页面加载时,接口返回或者手动将img标签的src属性设置为默认的占位图片,将图片的真实地址放在data-src属性上,再根据批量加载的频率,每隔一定时间,将部分img的src的内容设置为真实地址,直到全部替换。

此方式是在实现根据判断Img是否位于可视窗口内来加载图片较复杂的一种折中方式。通过requestAnimationFrame决定替换的时机,设定的是一秒加载2张图片。

    lazyLoadImg() {
        let count = 0;
        let idx = 0;
        let frame;
        this.isDomLoaded =false;
        const replaceImgSrc = () => {
            frame = window.requestAnimationFrame(replaceImgSrc);
            if (count % 30 === 0) {
                const container = document.querySelector(`#container`);
                if (!container) {
                    return;
                }
                const lazyImages = container.querySelectorAll('img[data-src]');
                if (idx === this.existsImgUrls.length) {
                    window.cancelAnimationFrame(frame);
                    return;
                }
                if (lazyImages.length) {
                    lazyImages[idx].setAttribute("src", this.existsImgUrls[idx]);
                    idx++;
                }
            }
            count++;
        }
        frame = window.requestAnimationFrame(replaceImgSrc);
    }

方式二: 只加载位于可视窗口中的图片

原理与方式一相同,都是先将图片的真实地址存放在data-src属性上,只是只有当元素处于可视范围中时才加载图片,在加载图片的时机上与方式一有区别。

    const imgs = document.getElementsByTagName("img");
    const viewHeight = window.innerHeight || document.documentElement.clientHeight;
    let num = 0;
function lazyLoad() {
    for (let i = num; i < imgs.length; i++) {
        // 用可视区域高度减去元素顶部距离可视区域顶部的高度
        let distance = viewHeight - imgs[i].getBoundingClientRect().top;
        // 如果可视区域高度大于等于元素顶部距离可视区域顶部的高度,说明元素露出
        if (distance >= 0) {
            // 给元素写入真实的src,展示图片
            imgs[i].src = imgs[i].getAttribute("data-src");
            // 前i张图片已经加载完毕,下次从第i+1张开始检查是否露出
            num = i + 1;
        }
    }
}

window.addEventListener('scroll', lazyLoad, false); // 此处需要使用防抖函数进行优化
复制代码

方式三: 使用Intersection Observer API

此方法在IE上不支持,如果要考虑IE浏览器时需要考虑兼容性。

    document.addEventListener("DOMContentLoaded", function() {
        let lazyImages = [...document.querySelectorAll('.lazy-load')];
        if ("IntersectionObserver" in window) {
            // 创建一个观察函数,以便待会调用   
            let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
                entries.forEach(function(entry) {
                    if (entry.isIntersecting) {
                        let lazyImage = entry.target;
                        lazyImage.src = lazyImage.dataset.src;   // 替换 src URL
                        lazyImageObserver.unobserve(lazyImage);  // 解除观察
                    }
                });
            });
            // 对所有需要懒加载的图片进行 “暗中观察”
            lazyImages.forEach(function(lazyImage) {
                lazyImageObserver.observe(lazyImage);
            });
        }else{
            alert('您的浏览器不支持 IntersectionObserver');
        }
    });
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享