1

在网页上加载一张图片往往需要很长的时间,这是影响用户体验的一个较大的因素。

我们可以将通过使用一些图片懒加载的技巧,来提高用户体验,增加网站的访问量。

就此,让我们开始了解什么是懒加载,并投入学习!

懒加载是Web和应用程序开发中的一组技术,可将页面上的资源加载推迟到以后需要这些资源时,而不是先加载它们。这些技术有助于提高性能,更好地利用设备资源并降低相关成本

这种技术旨在通过按需加载图片来提升网页的加载时间。

懒加载意味着,如果我们不主动地下滑查看位于页面底部的图片,这些图片是不会被加载的。

这种懒加载的技巧适用于页面上的任何资源(特指异步和耗时的资源)

在这篇教程中,我将给通过 Javascript 你展示一些图片懒加载的技巧。

技巧一:使用JavaScript的事件

1. 创建 HTML

  • 创建<img>。这个标签有 src 属性,用于加载图片。如果 src 被赋值, 将会根据相应地址加载图片。
<body>
  <img src="https://images.unsplash.com/photo-1482784160316-6eb046863ece?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" /> 
</body>
  • 为了阻止图片的加载,我们将图片的地址赋值给<img>中的 data-src 属性(data-src 并非 <img> 的标准属性,可随意指定)。
<body>
  <img class="lazy" data-src="https://images.unsplash.com/photo-1545105511-839f4a45a030?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80" />
</body>

2. 添加 CSS

  • 设置图片的宽(width)、高(height)、外边距(margin)
  • 将 display 设置为 block,以便使图像成为块级元素。在其上下有一些空白区。
<style>
  img {
    width: 500px;
    height: 350px;
    display: block;
    margin: 10px auto;
  }
</style>

准备工作已经完成。是时候告诉浏览器何时加载图片了。

我们需要三个事件:scroll, resize, orientationChange ,它们都同样的重要。scroll 事件会在页面展示时与元素滑动时执行。resize 会在窗口的大小改变时执行。orientationChange 会在设备的方向改变执行。这三个事件会监控屏幕和指定懒加载的图片,并触发图片的加载。

如果上述三个事件中的任何一个执行的话,我们将找到页面上所有指定懒加载的图片。通过图像的顶部偏移量、文档的顶部位置和窗口的高度来计算其中的哪些图片在视口(viewpoint)内。如果图片进入视口,我们将<img>中的 data-src 属性的值赋给 <img> 的 src 属性,当 <img> 的 src 属性被赋值,<img> 便会开始加载图片。

我们将指定懒加载的图片的 class 命名为 “lazy-load”,以便通过其找到这些图片。当图片加载之后,“lazy-load”和事件监听器都会被删除。

下面是示例的最终结果:

示例

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      img {
      width: 500px;
      height: 350px;
      display: block;
      margin: 10px auto;
      }
    </style>
  </head>
  <body>
    <img src="https://images.unsplash.com/photo-1482784160316-6eb046863ece?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
    <img src="https://images.unsplash.com/photo-1488441770602-aed21fc49bd5?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
    <img src="https://images.unsplash.com/photo-1426604966848-d7adac402bff?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjExMDk0fQ&auto=format&fit=crop&w=1050&q=80" />
    <img class="lazy-load" data-src="https://images.unsplash.com/photo-1545105511-839f4a45a030?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80" />
    <img class="lazy-load" data-src="https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
    <img class="lazy-load" data-src="https://images.unsplash.com/photo-1473800447596-01729482b8eb?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
    <img class="lazy-load" data-src="https://images.unsplash.com/photo-1491250974528-9443b2902f18?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
    <img class="lazy-load" data-src="https://images.unsplash.com/photo-1473800447596-01729482b8eb?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
    <img class="lazy-load" data-src="https://images.unsplash.com/photo-1500993855538-c6a99f437aa7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80" />
    <img class="lazy-load" data-src="https://images.unsplash.com/photo-1501018313157-78d10f597133?ixlib=rb-1.2.1&auto=format&fit=crop&w=1055&q=80" />
    <script> 
      document.addEventListener("DOMContentLoaded", function() {
        var lazyloadImages = document.querySelectorAll("img.lazy-load");    
        var lazyloadThrottleTimeout;  
        function lazyload () {
          if(lazyloadThrottleTimeout) {
            clearTimeout(lazyloadThrottleTimeout);
          }     
          lazyloadThrottleTimeout = setTimeout(function() {
              var scrollTop = window.pageYOffset;
              lazyloadImages.forEach(function(img) {
                  if(img.offsetTop < (window.innerHeight + scrollTop)) {
                    img.src = img.dataset.src;
                    img.classList.remove('lazy');
                  }
              });
              if(lazyloadImages.length == 0) { 
                document.removeEventListener("scroll", lazyload);
                window.removeEventListener("resize", lazyload);
                window.removeEventListener("orientationChange", lazyload);
              }
          }, 20);
        }
        document.addEventListener("scroll", lazyload);
        window.addEventListener("resize", lazyload);
        window.addEventListener("orientationChange", lazyload);
      });
    </script>
  </body>
</html>

技巧二: 使用 Intersection Observer API

Intersection Observer API 提供了一种异步方法,这种方法会自动"观察"元素是否可见。即目标元素是否与其祖先元素(或者顶级元素)的视口产生一个交叉区。这个 API 的使用避免了数学运算,并获得与前一种方法相同的结果。

通过 isIntersecting 属性的为真判断,我们将<img>中的 data-src 属性的值赋给 <img> 的 src 属性,当 <img> 的 src 属性被赋值,<img> 便会开始加载图片。之后,我们会将 class 的值 “lazy-load” 和 observer 从<img> 中删除。

Intersection Observer API 并不是所有的浏览器都支持

Intersection Observer API 的使用示例如下:

示例

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      img {
      width: 500px;
      height: 350px;
      display: block;
      margin: 10px auto;
      }
    </style>
  </head>
  <body>
    <img src="https://images.unsplash.com/photo-1482784160316-6eb046863ece?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
    <img src="https://images.unsplash.com/photo-1488441770602-aed21fc49bd5?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
    <img src="https://images.unsplash.com/photo-1426604966848-d7adac402bff?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjExMDk0fQ&auto=format&fit=crop&w=1050&q=80" />
    <img class="lazy-load" data-src="https://images.unsplash.com/photo-1545105511-839f4a45a030?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80" />
    <img class="lazy-load" data-src="https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
    <img class="lazy-load" data-src="https://images.unsplash.com/photo-1473800447596-01729482b8eb?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
    <img class="lazy-load" data-src="https://images.unsplash.com/photo-1491250974528-9443b2902f18?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
    <img class="lazy-load" data-src="https://images.unsplash.com/photo-1473800447596-01729482b8eb?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
    <img class="lazy-load" data-src="https://images.unsplash.com/photo-1500993855538-c6a99f437aa7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80" />
    <img class="lazy-load" data-src="https://images.unsplash.com/photo-1501018313157-78d10f597133?ixlib=rb-1.2.1&auto=format&fit=crop&w=1055&q=80" />
    <script> 
      document.addEventListener("DOMContentLoaded", function() {
        var lazyloadImages;    
        if ("IntersectionObserver" in window) {
          lazyloadImages = document.querySelectorAll(".lazy-load");
          var imageObserver = new IntersectionObserver(function(entries, observer) {
            entries.forEach(function(entry) {
              if (entry.isIntersecting) {
                var image = entry.target;
                image.src = image.dataset.src;
                image.classList.remove("lazy-load");
                imageObserver.unobserve(image);
              }
            });
          });
          lazyloadImages.forEach(function(image) {
            imageObserver.observe(image);
          });
        } else {  
          var lazyloadThrottleTimeout;
          lazyloadImages = document.querySelectorAll(".lazy-load");
          function lazyload () {
            if(lazyloadThrottleTimeout) {
              clearTimeout(lazyloadThrottleTimeout);
            }    
            lazyloadThrottleTimeout = setTimeout(function() {
              var scrollTop = window.pageYOffset;
              lazyloadImages.forEach(function(img) {
                  if(img.offsetTop < (window.innerHeight + scrollTop)) {
                    img.src = img.dataset.src;
                    img.classList.remove('lazy-load');
                  }
              });
              if(lazyloadImages.length == 0) { 
                document.removeEventListener("scroll", lazyload);
                window.removeEventListener("resize", lazyload);
                window.removeEventListener("orientationChange", lazyload);
              }
            }, 20);
          }
          document.addEventListener("scroll", lazyload);
          window.addEventListener("resize", lazyload);
          window.addEventListener("orientationChange", lazyload);
        }
      })
    </script>
  </body>
</html>

刘太刚
18 声望1 粉丝