前端图片懒加载原理(原生js)

1、懒加载用途

网页不断的追求美观大气,“瀑布流”布局等界面的元素的增多,使用过多的高清图片,因此严重影响加载速度,界面卡顿,白屏现象严重,并且流量消耗巨大,所以说按需延迟加载极大的解决了此类问题。
   vue、layui 等框架都标配了懒加载,多数人只停留在会用的程度上,究其原理,其实也不难,下面我们来看看 ==》》》

2、懒加载原理

图片之所以加载是因为src 属性指向了相应的图片地址,所以只需要不给它src属性即可。这里可以使用自定义属性data-src代替,将所有需要进行懒加载的图片存入数组中,通过监听网页scroll 属性,对即将进入页面的图片进行相应的加载;
  需要注意的地方有:
  1、函数节流,是必须的,scroll函数触发频率非常高,不加以“节制”,那身体可受不了。
  2、如何判断图片即将进入页面,这里需要牵扯到“视口”,还需要用到原生js中平时很少用到的一个函数-> getBoundingClientRect(),想了解看传送阵
  3、转载请注明出处,谢谢!

下面上完整代码:

<style>
    * {margin:0px;padding:0px;}
    #container {width:100%;margin:0 auto;display:flex;flex-wrap:wrap;box-sizing:border-box;}
    /*定制图片尺寸*/    .box {width:23%;padding:1%;}
    /*将承载图片的容器定制颜色及边框大小和圆角*/
    .boximg {box-shadow:0 0 5px #ccc;border:1px solid #cccccc;border-radius:5px;background:#888;}
    .boximg img {width:100%;height:auto;}
  </style>
</head>

<body>
  <div id="container">
    <div class="box">
      <div class="boximg"><img src="http://wlog.cn/demo/waterfall/images/001.jpg"></div>
    </div>
    <div class="box">
      <div class="boximg"><img src="http://wlog.cn/demo/waterfall/images/002.jpg"></div>
    </div>
    <div class="box">
      <div class="boximg"><img src="http://wlog.cn/demo/waterfall/images/003.jpg"></div>
    </div>
    <div class="box">
      <div class="boximg"><img src="http://wlog.cn/demo/waterfall/images/004.jpg"></div>
    </div>
    <div class="box">
      <div class="boximg"><img src="http://wlog.cn/demo/waterfall/images/005.jpg"></div>
    </div>
    <div class="box">
      <div class="boximg"><img src="http://wlog.cn/demo/waterfall/images/006.jpg"></div>
    </div>
    <div class="box">
      <div class="boximg"><img src="http://wlog.cn/demo/waterfall/images/007.jpg"></div>
    </div>
    <div class="box">
      <div class="boximg"><img src="http://wlog.cn/demo/waterfall/images/008.jpg"></div>
    </div>
    <div class="box">
      <div class="boximg"><img src="http://wlog.cn/demo/waterfall/images/009.jpg"></div>
    </div>
    <!-- 需要实现 懒加载的对象 添加类  imgLazyLoad  
          src 指向 使用 data-src 代替   -->
    <div class="box">
      <div class="boximg"><img class="imgLazyLoad" data-src="https://www.dowebok.com/demo/192/img/thumbnails/tibet-1.jpg"></div>
    </div>
    <div class="box">
      <div class="boximg"><img class="imgLazyLoad" data-src="https://www.dowebok.com/demo/192/img/thumbnails/tibet-2.jpg"></div>
    </div>
    <div class="box">
      <div class="boximg"><img class="imgLazyLoad" data-src="https://www.dowebok.com/demo/192/img/thumbnails/tibet-3.jpg"></div>
    </div>
    <div class="box">
      <div class="boximg"><img class="imgLazyLoad" data-src="https://www.dowebok.com/demo/192/img/thumbnails/tibet-4.jpg"></div>
    </div>
    <div class="box">
      <div class="boximg"><img class="imgLazyLoad" data-src="https://www.dowebok.com/demo/192/img/thumbnails/tibet-5.jpg"></div>
    </div>
    <div class="box">
      <div class="boximg"><img class="imgLazyLoad" data-src="https://www.dowebok.com/demo/192/img/thumbnails/tibet-6.jpg"></div>
    </div>

  </div>

  <script>
    (function () { //立即执行函数,防止污染全局
      let imgList = [], // 保存所有图片节点的数组
        delay, // 保存的是setTimeout生成的引用
        time = 250, //控制节流函数延迟执行的时间
        offset = 50; //设置图片距离可视区域多远则立即加载的偏差值

      function _delay() { //函数节流
        clearTimeout(delay);
        delay = setTimeout(() => {
          _loadImg();
        }, time)
      };

      function _loadImg() { //执行图片加载
        for (let i = 0, len = imgList.length; i < len; i++) {
          if (_isShow(imgList[i])) {
            imgList[i].src = imgList[i].getAttribute('data-src');
            imgList.splice(i, 1); //图片对象删除:每次判断图片需要显示并进行加载后从数组中取出此图片对象引用,避免下次循环重复判断
            // 数组被取出 1位 , 因此 为防止元素被跳过 需要 i-- , 并且 图片列表长度 -1  
            i--;
            len--;
          }
        }
      };

      function _isShow(el) { //判断img是否出现在可视窗口
        //该方法获得页面中某个元素的左,上,右和下分别相对 浏览器视窗 的位置 和 jquery 的 offset() 属性 相似 , 末尾跟上 left 、top 、 right 、 bottom 
        let coords = el.getBoundingClientRect();
        // 左边大括号 得出的是 图片顶部距->浏览器窗口  高度 , “ <= ” 右侧 是 浏览器窗口的 高度  加上 自定义的 偏移量
        return (coords.left >= 0 && coords.left >= 0 && coords.top) <= (document.documentElement.clientHeight ||
          window.innerHeight) + parseInt(offset);
      };

      function imgLoad(selector) { //获取所有需要实现懒加载图片对象引用并设置window监听事件scroll
        _selector = selector || '.imgLazyLoad';
        let nodes = document.querySelectorAll(selector);
        // 这里得到的只是个nodeList,所以这里利用Array.apply将nodes转变成一个数组保存到imgList中。(类数组 转 数组)
        imgList = Array.from(nodes);
        window.addEventListener('scroll', _delay, false)
      };
      imgLoad('.imgLazyLoad') //自定义 需要懒加载的图片 标识
    })()
  </script>

---------------------------------------------------------------------------------------------------------

每个步骤及含义,皆标注在代码块中了,还有不懂的欢迎下方留言!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值