js当中的图片懒加载,懒加载的一些概念和相关知识点

懒加载技术解析与实现
本文详细介绍了懒加载的概念,即元素仅在进入视口时加载,以此节省资源、加快网页响应速度并提升用户体验。文章通过实例展示了懒加载的原理,包括计算元素相对于窗口的位置,并在滚动时判断是否进入视口。同时提供了CSS、HTML和JavaScript代码实现懒加载的完整示例,演示了如何利用JavaScript监听滚动事件动态加载图片。

知道什么是懒加载

说通俗点就是轮到我我再出现,而不是一进入页面就出现
为什么需要
  1. 节省资源
  2. 加快网页打开
  3. 提升用户体育
  4. 巴拉巴拉

懒加载原理

红色为我们实际看到的浏览器窗口,黑色的为实际网页的长度

我们刚进入主页的时候

用户拖动滚动条,看到绿色的框框,这些绿色的框框才开始加载出来

必要知道的知识

  1. 获取元素距离顶部(body)的距离:元素.offsetTop

    1. 注意:如果元素的父元素(不管是祖父还是曾祖父还是亲生父亲),只要任意一个父亲开启了定位(不管是相对还是绝对),那么子元素的offsetTop属性值都是参考父元素的
    2. 如果父元素没有开启定位,那么就参考body
    3. 元素.offsetLeft同理
  2. 获取浏览器垂直滚动的距离:document.documentElement.onscrollTop

  3. offsetTop和offsetLeft 这两个属性,IE 、Opera和Firefox对它俩的解释存在差异:

    1. IE5.0+ 、Opera8.0+: offsetTop和offsetLeft 都是相对父级元素
    2. Firefox1.06: offsetTop和offsetLeft 都是相对于body元素
  4. 为了解决父元素如果开启定位的问题,我们可以使用offsetParent加循环获取距离body的距离

            //获取元素距离body的top值和left值
            function getPoint(obj) {
                //记录left的值
                var left = 0;
                //记录top的值
                var top = 0;
                //如果需要减去边框的距离,可以解除下面这二行注释
                //var borderLeftWidth;
                //var borderTopWidth;
                
                //如果obj.offsetParent获取不到父级了,就会跳出循环
                while (obj) {
                    left = left + obj.offsetLeft;
                    top = top + obj.offsetTop;
                    //如果需要减去边框的距离,可以解除下面这二行注释,并将前二行注释
                    //left = left + obj.offsetLeft - borderLeftWidth;
                    //top = top + obj.offsetTop - borderTopWidth;
                    obj = obj.offsetParent;
                }
                //返回距离body的left值和top值
                return {
                    left,
                    top
                };
            }
    

实现懒加载

  1. 一开始的思路(错误的):

    1. 先获取元素距离可视窗口顶部的距离,然后再和可视窗口的高度进行比较,如果小于可视窗口的高度,就加载出来(错误,因为二者距离都是死的)
  2. 后来的思路(正确的)

    1. 还是依旧获取元素距离可是窗口顶部的距离,然后再和(可视窗口的高度+滚动的距离)进行比较,如果某一个元素距离顶部距离小于这二者之和的距离,则元素里面的资源加载出来
    代码
    css代码
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            body,
            html {
                width: 100%;
                height: 100%;
            }
            img {
                vertical-align: bottom;
                display: inline;
                width: 590px;
                height: 500px;
            }
            .content {
                width: 1200px;
                margin: 0 auto;
            }
        </style>
    
    HTML代码
        <div class="header">
            <h2>图片展示</h2>
        </div>
        <div class="content">
            <img data-src="./img/01.jpg" alt="">
            <img data-src="./img/02.jpg" alt="">
            <img data-src="./img/03.jpg" alt="">
            <img data-src="./img/04.jpg" alt="">
            <img data-src="./img/05.jpg" alt="">
            <img data-src="./img/06.jpg" alt="">
            <img data-src="./img/07.jpg" alt="">
            <img data-src="./img/08.jpg" alt="">
            <img data-src="./img/09.jpg" alt="">
            <img data-src="./img/10.jpg" alt="">
            <img data-src="./img/10.jpg" alt="">
            <img data-src="./img/11.jpg" alt="">
            <img data-src="./img/12.jpg" alt="">
        </div>
    
    JavaScript代码
    <script>
            //获取元素距离body的top值和left值
            function getPoint(obj) {
                var left = 0;
                var top = 0;
                while (obj) {
                    left = left + obj.offsetLeft;
                    top = top + obj.offsetTop;
                    obj = obj.offsetParent;
                }
                return {
                    left,
                    top
                };
            }
            //防止图片没有加载出来获取不到图片的offsetTop值,就填加了一个window.onload事件
    		//页面初始化(用户刚刚进入页面的时候)
            window.onload = function () {
                var domHeight = document.documentElement.clientHeight; //视口的高度
                var imgs = document.querySelectorAll("img");
                //然后循环
                //每一个元素判断距离body的值是否 小于 (可视窗口的高度+垂直滚动的距离)
                for (var v of imgs) {
                    if (getPoint(v).top < (domHeight + document.documentElement.scrollTop)) {
                        //显示图片
                        // v.src=v.dataset.src;也可以获取自定义属性值
                        v.src = v.getAttribute("data-src");
                    }
                }
            }
    		//滚动事件
            window.onscroll = function () {
                var domHeight = document.documentElement.clientHeight; //视口的高度
                var imgs = document.querySelectorAll("img");
                //然后循环
                for (var v of imgs) {
                    //每一个元素判断距离body的值是否 小于 (可视窗口的高度+垂直滚动的距离)
                    if (getPoint(v).top < (domHeight + document.documentElement.scrollTop)) {
                        //显示图片
                        // v.src=v.dataset.src;
                        v.src = v.getAttribute("data-src");
                    }
                }
            }
        </script>
    

    展示效果

    可以看到图片不是一次性加载出来,而是随着滚动条滚动才加载出来的

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未成年梦想

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值