图片懒加载

认识图片懒加载

  • 定义:在网页中视图之外的图片默认不加载,随着页面的滚动,图片进入了显示的范围,则触发图片的加载显示
  • 目的:提高页面的加载速度,让用户体验感更好并且节省流量;比如在一些电商网站上需要展示大量的商品图片信息,如果打开网页时让所有图片一次性加载完成,需要处理很多次网络请求,等待加载时间比较长,用户体验感很差
  • 原理:初始化时,图片标签的src不是真实的图片地址;而统一使用白图或者透明图代替;由于所有图片都使用这一张图片,只会发送一次请求,不会增加性能负担。然后将图片的真实路径绑定给一个自定义属性,例如data-url;然后监听滚动事件当图片元素进入视口时,就将src替换为真正的url地址。

如何判断一个元素是否在可视区域?

图片懒加载的实现方法

实现方式:

  • 滚动监听+scrollTop+offsetTop+innerHeight
<script>
        /*
            图片懒加载
                1.获取所有的图片  每张图片的src属性中都统一绑定同一张白图或者透明图片 在自定义属性data-src上绑定真实的图片
                2.图片懒加载要在window上绑定一个监听滚动事件
                3.获取每一张图片距离浏览器窗口顶部的距离
                    浏览器可视区域的高度window.innerHeight
                    浏览器卷出高度document.documentElement.scrollTop||document.body.scrollTop
                    图片距离网页顶部的距离img.offsetTop
                4.当某张图片距离顶部的距离小于浏览器的窗口的时候,那么该图片就加载显示
                  scrollTop+innerHeight > offsetTop,即图片在视口内,否则图片在可视区域外
             */
            const imgs = document.querySelectorAll("img")
                let flag = []
                for (let i = 0; i < imgs.length; i++) {
                    flag[i] = true   //使图片只加载一次
                }
                //  需要有一个滚动事件
                window.addEventListener("scroll", (e) => {
                    // 要监听浏览器的滚动事件
                    // 获取每一张图片距离顶部的距离 => 遍历图片
                    for (let i = 0; i < imgs.length; i++) {
                        // 获取每一张图片距离浏览器顶部的距离
                        let imgTop = imgs[i].offsetTop
                        let scrollTop = document.documentElement.scrollTop || document.body.scrollTop
                        let windowH = window.innerHeight
                        if (imgTop <(windowH + scrollTop)&& flag[i]) {
                            flag[i] = false  //开关思想
                            console.log(i);
                            // 让img身上的data-src的地址显示到src的身上
                            imgs[i].src = imgs[i].dataset.src
                        }
                    }
                })

    </script>
  • 滚动监听+getBoundingClientRect().top+window.innerHeight 当图片距离顶部的距离小于浏览器的窗口的时候,那么就图片加载显示
    <script>
        /*
            图片懒加载
                1.获取所有的图片  每张图片的src属性中都统一绑定同一张白图或者透明图片 在自定义属性data-src上绑定真实的图片
                2.图片懒加载要在window上绑定一个监听滚动事件
                3.获取每一张图片距离浏览器窗口顶部的距离
                    img.getBoundingClientRect().top => 获取img距离浏览器可视区域顶部的距离
                    window.innerHeight=>获取浏览器可视区域的高度
                4.当某张图片距离顶部的距离小于浏览器的窗口的时候,那么该图片就加载显示 
         */

        const imgs = document.querySelectorAll("img")
        let flag= [] 
        for (let i = 0; i < imgs.length; i++) {
            flag[i] = true   //使图片只加载一次
        }
        //  需要有一个滚动事件
        window.addEventListener("scroll",(e)=>{
            // 要监听浏览器的滚动事件
            // 距离浏览器可视区域顶部的距离 => 遍历图片
            for(let i=0;i<imgs.length;i++){
                // 获取每一张图片距离浏览器可视区域顶部的距离
                let imgTop = imgs[i].getBoundingClientRect().top
                // 浏览器可视区域的宽高
                let windowH = window.innerHeight
                if(imgTop<windowH && flag[i]){
                    flag[i] = false  //开关思想
                    console.log(i);
                    // 让img身上的data-src的地址显示到src的身上
                    imgs[i].src = imgs[i].dataset.src
                }
            }
        })
    </script>
  • 使用监听器来监听图片与视口的交叉 intersectionObserver() 监听图片与视口的交叉 => o.observe(img);监听到的图片是否交叉 => imgItem.isIntersecting;当为true时就用真正的图片路径替换src,然后使用o.unobserve(img) 不再监听视口交叉;这种方式比上面的方式更好,因为监听到后就可以关闭,而上面方式需要频繁监听scroll事件,会有一定的性能损耗;但是Intersection Observer API会有浏览器兼容问题!!
 <script>
        /*
            使用监听器来监听图片与视口的交叉
            创建监听器 => const o = new IntersectionObserver(callback) 
            监听图片与视口的交叉 => o.observe(img) => 在监听的过程当中应该是一张一张地监听
            不监听图片与视口的交叉 => o.unobserve(img)
            监听到的图片是否交叉 => imgItem.isIntersecting => 如果为true那么表示图片与视口交叉 否则就false
         */

        //  监听到之后的处理 imgs=>你监听到的图片加工成的一个数组

        const callback = imgs => {
            console.log(imgs);
            imgs.forEach(imgItem=>{
                // 获取那一张监听到的图片
                if(imgItem.isIntersecting){ //图片与视口交叉  此时要加载图片
                    // 将图片里面的data-src地址给src
                    imgItem.target.src = imgItem.target.dataset.src
                    // 不要再监听
                    o.unobserve(imgItem.target)
                }
            })
        }

        const o = new IntersectionObserver(callback)
        // 监听页面当中的图片  获取所有图片
        const images = document.querySelectorAll("img")
        for(let i=0;i<images.length;i++){
            // 每一张图片都要监听
            o.observe(images[i])
        }
    </script>
posted @   饼MIN  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示