JavaScript 事件

我们需要滚动、调整大小和orientationChange 事件,它们同样重要:

<!DOCTYPE html>
<html>
  <head>
    <title>文档的标题</title>
    <style>
      img {
        width: 500px;
        height: 350px;
        display: block;
        margin: 10px auto;
      }
    </style>
  </head>
  <body>
    <img src="https://onitroad.com/photo-2482784160316-6eb046863ece.png" />
    <img src="https://onitroad.com/photo-2488441770602-6ed21fc49bd5.png" />
    <img src="https://onitroad.com/photo-2426604966848-67adac402bff.png" />
    <img class="lazy-load" data-src="https://onitroad.com/photo-2545105511-639f4a45a030.png" />
    <img class="lazy-load" data-src="https://onitroad.com/photo-2493246507139-61e8fad9978e.png" />
    <img class="lazy-load" data-src="https://onitroad.com/photo-2473800447596-61729482b8eb.png" />
    <img class="lazy-load" data-src="https://onitroad.com/photo-2491250974528-6443b2902f18.png" />
    <img class="lazy-load" data-src="https://onitroad.com/photo-2473800447596-61729482b8eb.png" />
    <img class="lazy-load" data-src="https://onitroad.com/photo-2500993855538-66a99f437aa7.png" />
    <img class="lazy-load" data-src="https://onitroad.com/photo-2501018313157-68d10f597133.png" />
    <script>
      document.addEventListener("DOMContentLoaded", function() {
        let lazyloadImages = document.querySelectorAll("img.lazy-load");
        let lazyloadThrottleTimeout;
        function lazyload() {
          if(lazyloadThrottleTimeout) {
            clearTimeout(lazyloadThrottleTimeout);
          }
          lazyloadThrottleTimeout = setTimeout(function() {
            let 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>

当文档视图或者元素被滚动时,滚动事件会报告。
当文档视图(窗口)被调整大小时,resize 事件会报告,当设备的方向发生变化时,orientationChange 事件会报告。
这三个事件捕捉屏幕中的变化并指定可见图像的数量并触发它们加载。

如果存在这些事件中的任何一个,我们将在页面上找到所有延迟的图片,并检查当前哪些图片在视口中。
它通过图像的顶部偏移、文档的顶部位置和窗口的高度执行。
如果图像已进入视口,我们从 data-src 属性中选取 URL 并将其移动到 src 属性以加载图像。

使用 JavaScript 延迟加载图片

在网页上加载图片可能需要很长时间。
这是一个影响用户体验的大问题,因为访问者在访问内容之前必须等待。
我们将介绍一些延迟加载图片的技术,这些技术可以改善用户体验并增加 Web 访问者的数量。

在本教程中,我们将展示一些使用 JavaScript 延迟加载图像的技术。

路口观察者API

我们可以使用 Intersection Observer API 获得相同的结果:

<!DOCTYPE html>
<html>
  <head>
    <title>文档的标题</title>
    <style>
      img {
        width: 500px;
        height: 350px;
        display: block;
        margin: 10px auto;
      }
    </style>
  </head>
  <body>
    <img src="https://onitroad.com/photo-2482784160316-6eb046863ece.png" />
    <img src="https://onitroad.com/photo-2488441770602-6ed21fc49bd5.png" />
    <img src="https://onitroad.com/photo-2426604966848-67adac402bff.png" />
    <img class="lazy-load" data-src="https://onitroad.com/photo-2545105511-639f4a45a030.png" />
    <img class="lazy-load" data-src="https://onitroad.com/photo-2493246507139-61e8fad9978e.png" />
    <img class="lazy-load" data-src="https://onitroad.com/photo-2473800447596-61729482b8eb.png" />
    <img class="lazy-load" data-src="https://onitroad.com/photo-2491250974528-6443b2902f18.png" />
    <img class="lazy-load" data-src="https://onitroad.com/photo-2473800447596-61729482b8eb.png" />
    <img class="lazy-load" data-src="https://onitroad.com/photo-2500993855538-66a99f437aa7.png" />
    <img class="lazy-load" data-src="https://onitroad.com/photo-2501018313157-68d10f597133.png" />
    <script>
      document.addEventListener("DOMContentLoaded", function() {
        let lazyloadImages;
        if("IntersectionObserver" in window) {
          lazyloadImages = document.querySelectorAll(".lazy-load");
          let imageObserver = new IntersectionObserver(function(entries, observer) {
            entries.forEach(function(entry) {
              if(entry.isIntersecting) {
                let image = entry.target;
                image.src = image.dataset.src;
                image.classList.remove("lazy-load");
                imageObserver.unobserve(image);
              }
            });
          });
          lazyloadImages.forEach(function(image) {
            imageObserver.observe(image);
          });
        } else {
          let lazyloadThrottleTimeout;
          lazyloadImages = document.querySelectorAll(".lazy-load");
          function lazyload() {
            if(lazyloadThrottleTimeout) {
              clearTimeout(lazyloadThrottleTimeout);
            }
            lazyloadThrottleTimeout = setTimeout(function() {
              let 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>

并非所有浏览器都支持使用 Intersection Observer API 延迟加载图像。

Intersection Observer API 提供了一种异步观察目标元素与祖先元素或者顶级文档视口的交集变化的方法。
它允许避免数学运算并获得与前一种方法相同的结果。

isIntersecting 属性用于从 data-src 属性中选取 URL 并将其移动到 src 属性以触发图像加载。
执行此操作后,我们从该图像中删除“延迟加载”类和观察者。

日期:2020-06-02 22:16:28 来源:oir作者:oir