最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 原生JS实现图片懒加载

    正文概述 掘金(create_null)   2021-05-12   432

    为什么需要懒加载?

    在一些图片比较多的网站(比如说大型电商网站)图片是非常多的,如果我们在打开网页的一瞬间就把网站的所有图片加载出来,很有可能造成卡顿和白屏的现象,用户体验变得极其的差,要是遇到脾气暴躁的小伙伴相信直接反手就是一个Ctrl+W。
    因为图片真的很多,一瞬间就把网站的所有图片加载出来浏览器短时间内根本处理不完,但是我们打开网站的那一瞬间仅仅只能看到视口内的图片,这时候去加载网页最底部的图片是非常浪费资源和没有必要的,所以遇到这种情况使用懒加载技术就显得尤为必要了。

    懒加载实现原理

    懒加载的原理其实很简单,就是预先将图片真实的src放在我们自定义的属性里面(比如data-src),当图片出现在了我们的视口范围之内的时候,再把data-src赋值给src属性,完成图片加载。

    // 页面初始化时
    <img data-src="https://img11.360buyimg.com/pop/s590x470.jpg.webp" />
    
    // 当图片出现在了视口范围之内
    <img data-src="https://img11.360buyimg.com/pop/s590x470.jpg.webp" src="https://img11.360buyimg.com/pop/s590x470.jpg.webp"/>
    

    这里有个点就是初始化时可以不给img标签加上src属性,因为只要存在src属性,浏览器就会去执行一次请求将其指向的资源下载并应用到文档内,这里不加上可以提升一些性能

    具体实现

    基于前面讲解的思路,我们自己手写一个懒加载

    新建一个lazyload.html文件,初始化dom结构并设置对应的样式

    <!DOCTYPE html>
    <html>
    <head>
      <title>lazy load</title>
      <style>
        .img {
          width: 220px;
          height: 220px;
          background-color: #ccc;
          margin-bottom: 40px;
          margin-left: 50px;
        }
    
        .pic {
          width: 100%;
          height: 100%;
        }
      </style>
    </head>
    
    <body>
      <div class="container">
      <!--将真实的src先放在data-src中-->
        <div class="img">
          <img class="pic"  data-src="https://img10.360buyimg.com/n7/jfs/t1/183679/11/2189/143829/6091f5d8E933e7ad1/e3e2001666f2ce7b.jpg" />
        </div>
        <div class="img">
          <img class="pic"  data-src="https://img12.360buyimg.com/n7/jfs/t1/192682/11/617/163213/608b887aEddbbbee3/9570466a90d02f79.jpg" />
        </div>
        <div class="img">
          <img class="pic"  data-src="https://img14.360buyimg.com/n7/jfs/t1/156161/35/18802/268242/60641d96Eca3dee7f/4a32070a19deb4f5.jpg" />
        </div>
        <div class="img">
          <img class="pic"  data-src="https://img10.360buyimg.com/n7/jfs/t1/130179/12/9273/167054/5f5468edE9d4ecd9c/39f7520d9f76b695.jpg" />
        </div>
        <div class="img">
          <img class="pic"  data-src="https://img14.360buyimg.com/n7/jfs/t1/100888/13/13132/105320/5e5533c6Ea8daa487/f95d7ba4da5581c5.jpg" />
        </div>
        <div class="img">
          <img class="pic"  data-src="https://img10.360buyimg.com/n7/jfs/t1/173986/31/8862/291849/6098d6d0E26c55012/c2144f6e074556d2.jpg" />
        </div>
        <div class="img">
          <img class="pic"  data-src="https://img10.360buyimg.com/n7/jfs/t1/110754/4/12605/101916/5ee43244E6fbf9433/c42fb5e3f9558a59.jpg" />
        </div>
        <div class="img">
          <img class="pic"  data-src="https://img10.360buyimg.com/n7/jfs/t1/148370/31/1084/45848/5eedc2eeEfdc2cd46/f3c3a6f0bd7998be.jpg" />
        </div>
        <div class="img">
          <img class="pic"  data-src="https://img10.360buyimg.com/n7/jfs/t1/165930/8/7273/171076/602fd5dfE65a52775/ee27074b7037c020.jpg" />
        </div>
        <div class="img">
          <img class="pic"  data-src="https://img13.360buyimg.com/n7/jfs/t1/190093/28/117/193777/60867822Ea949fbec/6fe51b122d0fdc5a.jpg" />
        </div>
        <div class="img">
          <img class="pic"  data-src="https://img14.360buyimg.com/n7/jfs/t1/119501/15/6768/115886/5eca6c36Eb3541dc9/2f4534173878a23c.jpg" />
        </div>
      </div>
      </body>
      </html>
    

    接下来是JS部分,我们需要提前知道几个值,一个是当前浏览器窗口的视口高度,另一个是每张图片距离视口顶部的距离,因为只有当图片距离顶部的距离小于我们的视口高度,那么就代表这张图片已经出现在我们的视口范围内了。

    获取浏览器视口高度

    获取可视区域的高度我们通常使用window.innerHeight就可以拿到了,当然如果需要兼容低版本IE浏览器的话则可以使用document.documentElement.clientHeight来获取,这里我们做一个兼容处理

    const viewPortHeight = window.innerHeight || document.documentElement.clientHeight
    

    获取图片离顶部的距离

    这里我们简单粗暴一点,直接使用getBoundingClientRect()这个方法来获取,对这个方法不了解的小伙伴可以点击这里进行查看

    到这里,我们所需要的两个值就都可以拿到了,下面直接上代码:

    // 获取所有图片
    const imgList = document.querySelectorAll('img')
    // 用于记录当前显示到了哪一张图片
    let index = 0;
    function lazyload() {
      // 获取浏览器视口高度,这里写在函数内部是考虑浏览器窗口大小改变的情况
      const viewPortHeight = window.innerHeight || document.documentElement.clientHeight
      for (let i = index; i < imgList.length; i++) {
        // 这里用可视区域高度减去图片顶部距离可视区域顶部的高度
        const distance = viewPortHeight - imgList[i].getBoundingClientRect().top;
        // 如果可视区域高度大于等于元素顶部距离可视区域顶部的高度,说明图片已经出现在了视口范围内
        if (distance >= 0) {
          // 给图片赋值真实的src,展示图片
          imgList[i].src = imgList[i].getAttribute('data-src');
          // 前i张图片已经加载完毕,下次从第i+1张开始检查是否需要显示
          index = i + 1;
        }
      }
    }
    
    // 定义一个防抖函数
    function debounce(fn, delay = 500, ...args) {
      let timer = null;
      // 这里的e是event事件对象
      return function (e) {
        if (timer) clearTimeout(timer);
        timer = setTimeout(() => {
          fn.apply(this, args);
        }, delay);
      };
    }
    
    // 页面加载完成执行一次lazyload,渲染第一次打开的网页视口内的图片
    window.onload = lazyload;
    // 监听Scroll事件,为了防止频繁调用,使用防抖函数进行优化
    window.addEventListener("scroll", debounce(lazyload, 600));
    // 浏览器窗口大小改变时重新计算
    window.addEventListener("resize", debounce(lazyload, 600));
    

    最后效果

    到这里我们的图片懒加载就写完了,下面是效果图,喜欢的朋友麻烦点个赞吧

    原生JS实现图片懒加载


    起源地下载网 » 原生JS实现图片懒加载

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元