实现图片的延迟加载

一、HTML结构分析如下:

class属性:在js中使用类选择器选取需要延迟加载处理的<img>标签。

src属性:加载当前的占位符图片,可用Base64图片或者第分辨率的图片。

data-src属性:通过该自定义的url存放真实的图片URL。

二、JavaScript 实现逻辑如下:

    在文档的 DOMContentLoaded() 事件中,添加延迟加载处理逻辑,首先获取class属性名为lazy的所有<img>标签,将这些标签暂存在一个名为lazyImages的数组中,表示需要进行延迟加载当未完成加载的图片集合,当一个图片被加载后,便将其从lazyImages数组中移除,当lazyImages数组为空的时,表示所有待延迟加载的图片均已加载完毕,此时需要取消对页面滚动的事件监听。

getBoundingClientRect() 函数:获取元素的相对位置:

 三、具体代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>传统方式实现图片延迟加载</title>
</head>
<body>
    <img 
    class="lazy"
    src="https://preview.qiantucdn.com/weitu/79/12/80/43Z58PICGe3yQDKVMapgj_PIC2018.jpg!kuan320"
    data-src="https://preview.qiantucdn.com/weitu/37/15/64/92K58PICyxVWiGkVTmRBA_PIC2018.jpg!kuan320"
    width="500" height="300" alt="2.jpg">
    <img 
    class="lazy"
    src="https://preview.qiantucdn.com/weitu/79/12/80/43Z58PICGe3yQDKVMapgj_PIC2018.jpg!kuan320"
    data-src="https://preview.qiantucdn.com/weitu/82/60/34/59458PICvTPMGbBX9U3py_PIC2018.jpg!kuan320"
    width="500" height="300" alt="3.jpg">
    <img 
    class="lazy"
    src="https://preview.qiantucdn.com/weitu/79/12/80/43Z58PICGe3yQDKVMapgj_PIC2018.jpg!kuan320"
    data-src="https://preview.qiantucdn.com/weitu/52/74/06/91r58PICdHZiGe6EcTiNY_PIC2018.jpg!kuan320"
    width="500" height="300" alt="4.jpg">
    <img 
    class="lazy"
    src="https://preview.qiantucdn.com/weitu/79/12/80/43Z58PICGe3yQDKVMapgj_PIC2018.jpg!kuan320"
    data-src="https://preview.qiantucdn.com/weitu/37/15/64/92K58PICyxVWiGkVTmRBA_PIC2018.jpg!kuan320"
    width="500" height="300" alt="2.jpg">
    <img 
    class="lazy"
    src="https://preview.qiantucdn.com/weitu/79/12/80/43Z58PICGe3yQDKVMapgj_PIC2018.jpg!kuan320"
    data-src="https://preview.qiantucdn.com/weitu/82/60/34/59458PICvTPMGbBX9U3py_PIC2018.jpg!kuan320"
    width="500" height="300" alt="3.jpg">
    <img 
    class="lazy"
    src="https://preview.qiantucdn.com/weitu/79/12/80/43Z58PICGe3yQDKVMapgj_PIC2018.jpg!kuan320"
    data-src="https://preview.qiantucdn.com/weitu/52/74/06/91r58PICdHZiGe6EcTiNY_PIC2018.jpg!kuan320"
    width="500" height="300" alt="4.jpg">
    <img 
    class="lazy"
    src="https://preview.qiantucdn.com/weitu/79/12/80/43Z58PICGe3yQDKVMapgj_PIC2018.jpg!kuan320"
    data-src="https://preview.qiantucdn.com/weitu/37/15/64/92K58PICyxVWiGkVTmRBA_PIC2018.jpg!kuan320"
    width="500" height="300" alt="2.jpg">
    <img 
    class="lazy"
    src="https://preview.qiantucdn.com/weitu/79/12/80/43Z58PICGe3yQDKVMapgj_PIC2018.jpg!kuan320"
    data-src="https://preview.qiantucdn.com/weitu/82/60/34/59458PICvTPMGbBX9U3py_PIC2018.jpg!kuan320"
    width="500" height="300" alt="3.jpg">
    <img 
    class="lazy"
    src="https://preview.qiantucdn.com/weitu/79/12/80/43Z58PICGe3yQDKVMapgj_PIC2018.jpg!kuan320"
    data-src="https://preview.qiantucdn.com/weitu/52/74/06/91r58PICdHZiGe6EcTiNY_PIC2018.jpg!kuan320"
    width="500" height="300" alt="4.jpg">
    <img 
    class="lazy"
    src="https://preview.qiantucdn.com/weitu/79/12/80/43Z58PICGe3yQDKVMapgj_PIC2018.jpg!kuan320"
    data-src="https://preview.qiantucdn.com/weitu/37/15/64/92K58PICyxVWiGkVTmRBA_PIC2018.jpg!kuan320"
    width="500" height="300" alt="2.jpg">
    <img 
    class="lazy"
    src="https://preview.qiantucdn.com/weitu/79/12/80/43Z58PICGe3yQDKVMapgj_PIC2018.jpg!kuan320"
    data-src="https://preview.qiantucdn.com/weitu/82/60/34/59458PICvTPMGbBX9U3py_PIC2018.jpg!kuan320"
    width="500" height="300" alt="3.jpg">
    <img 
    class="lazy"
    src="https://preview.qiantucdn.com/weitu/79/12/80/43Z58PICGe3yQDKVMapgj_PIC2018.jpg!kuan320"
    data-src="https://preview.qiantucdn.com/weitu/52/74/06/91r58PICdHZiGe6EcTiNY_PIC2018.jpg!kuan320"
    width="500" height="300" alt="4.jpg">
    <img 
    class="lazy"
    src="https://preview.qiantucdn.com/weitu/79/12/80/43Z58PICGe3yQDKVMapgj_PIC2018.jpg!kuan320"
    data-src="https://preview.qiantucdn.com/weitu/37/15/64/92K58PICyxVWiGkVTmRBA_PIC2018.jpg!kuan320"
    width="500" height="300" alt="2.jpg">
    <img 
    class="lazy"
    src="https://preview.qiantucdn.com/weitu/79/12/80/43Z58PICGe3yQDKVMapgj_PIC2018.jpg!kuan320"
    data-src="https://preview.qiantucdn.com/weitu/82/60/34/59458PICvTPMGbBX9U3py_PIC2018.jpg!kuan320"
    width="500" height="300" alt="3.jpg">
    <img 
    class="lazy"
    src="https://preview.qiantucdn.com/weitu/79/12/80/43Z58PICGe3yQDKVMapgj_PIC2018.jpg!kuan320"
    data-src="https://preview.qiantucdn.com/weitu/52/74/06/91r58PICdHZiGe6EcTiNY_PIC2018.jpg!kuan320"
    width="500" height="300" alt="4.jpg">
    <img 
    class="lazy"
    src="https://preview.qiantucdn.com/weitu/79/12/80/43Z58PICGe3yQDKVMapgj_PIC2018.jpg!kuan320"
    data-src="https://preview.qiantucdn.com/weitu/37/15/64/92K58PICyxVWiGkVTmRBA_PIC2018.jpg!kuan320"
    width="500" height="300" alt="2.jpg">
    <img 
    class="lazy"
    src="https://preview.qiantucdn.com/weitu/79/12/80/43Z58PICGe3yQDKVMapgj_PIC2018.jpg!kuan320"
    data-src="https://preview.qiantucdn.com/weitu/82/60/34/59458PICvTPMGbBX9U3py_PIC2018.jpg!kuan320"
    width="500" height="300" alt="3.jpg">
    <img 
    class="lazy"
    src="https://preview.qiantucdn.com/weitu/79/12/80/43Z58PICGe3yQDKVMapgj_PIC2018.jpg!kuan320"
    data-src="https://preview.qiantucdn.com/weitu/52/74/06/91r58PICdHZiGe6EcTiNY_PIC2018.jpg!kuan320"
    width="500" height="300" alt="4.jpg">
</body>
<script>
    //当初始化的HTML文档被完全加载和解析完成之后,该事件被触发,而无需等待样式表、图像和子框架的完全加载;
    document.addEventListener('DOMContentLoaded',function() {
        //获取所有需要延迟加载的图片
        let lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));
        //限制函数被频繁调用
        let active = false;
        const lazyLoad = function() {
            if(active === false){
                active = true;
                setTimeout(function(){
                    lazyImages.forEach(function(lazyImage) {
                        //判断图片是否出现在视窗中
                        //getBoundingClientRect:用于获取某个元素相对于视窗的位置集合
                        if((lazyImage.getBoundingClientRect().top <= window.innerHeight 
                        && lazyImage.getBoundingClientRect().bottom >= 0) 
                        /***
                         * element.style 既支持读(样式)也支持写,
                         * getComputedStyle 仅支持读并不支持写入。
                         */
                        &&  getComputedStyle(lazyImage).display !== "none"){
                            //将真实的图片url赋值给src属性,发起请求加载资源
                            lazyImage.src = lazyImage.dataset.src;//用元素节点对象的dataset属性,它指向一个对象,可以用来操作HTML元素标签的data-*属性。
                            //图片加载完成后,需取消监控以防止重复加载
                            lazyImage.classList.remove("lazy");//classList:返回一个元素的类属性
                            lazyImages = lazyImages.filter(image => {
                                return image !==lazyImage;
                            });
                            //所有延迟加载图片加载完成后,移除事件触发处理函数
                            if(lazyImages.length === 0){
                                document.addEventListener("scroll",lazyLoad);
                                window.addEventListener("resize",lazyLoad);
                                window.addEventListener("orientationchange",lazyLoad);
                            }   
                        }
                    });
                    active = false;
                },200)
            } 
        }
        lazyLoad();//初始化加载
        //滚动页面时触发
        document.addEventListener("scroll",lazyLoad);
        //发生窗口大小改变时触发
        window.addEventListener("resize",lazyLoad);
        //在设备的纵横方向改变时触发。
        window.addEventListener("orientationchange",lazyLoad);
    });
   
</script>
</html>
未来的我会感谢现在努力的自己。
原文地址:https://www.cnblogs.com/cat-eol/p/15104823.html