实例

惰性加载(lazy load)

有时,我们希望某些静态资源(比如图片),只有用户向下滚动,它们进入视口时才加载,这样可以节省带宽,提高网页性能。这就叫做“惰性加载”。

有了 IntersectionObserver API,实现起来就很容易了。图像的 HTML 代码可以写成下面这样。

  1. <img src="placeholder.png" data-src="img-1.jpg">
  2. <img src="placeholder.png" data-src="img-2.jpg">
  3. <img src="placeholder.png" data-src="img-3.jpg">

上面代码中,图像默认显示一个占位符,data-src属性是惰性加载的真正图像。

  1. function query(selector) {
  2. return Array.from(document.querySelectorAll(selector));
  3. }
  4. var observer = new IntersectionObserver(
  5. function(entries) {
  6. entries.forEach(function(entry) {
  7. entry.target.src = entry.target.dataset.src;
  8. observer.unobserve(entry.target);
  9. });
  10. }
  11. );
  12. query('.lazy-loaded').forEach(function (item) {
  13. observer.observe(item);
  14. });

上面代码中,只有图像开始可见时,才会加载真正的图像文件。

无限滚动

无限滚动(infinite scroll)指的是,随着网页滚动到底部,不断加载新的内容到页面,它的实现也很简单。

  1. var intersectionObserver = new IntersectionObserver(
  2. function (entries) {
  3. // 如果不可见,就返回
  4. if (entries[0].intersectionRatio <= 0) return;
  5. loadItems(10);
  6. console.log('Loaded new items');
  7. }
  8. );
  9. // 开始观察
  10. intersectionObserver.observe(
  11. document.querySelector('.scrollerFooter')
  12. );

无限滚动时,最好像上例那样,页面底部有一个页尾栏(又称sentinels,上例是.scrollerFooter)。一旦页尾栏可见,就表示用户到达了页面底部,从而加载新的条目放在页尾栏前面。否则就需要每一次页面加入新内容时,都调用observe()方法,对新增内容的底部建立观察。

视频自动播放

下面是一个视频元素,希望它完全进入视口的时候自动播放,离开视口的时候自动暂停。

  1. <video src="foo.mp4" controls=""></video>

下面是 JS 代码。

  1. let video = document.querySelector('video');
  2. let isPaused = false;
  3. let observer = new IntersectionObserver((entries, observer) => {
  4. entries.forEach(entry => {
  5. if (entry.intersectionRatio != 1 && !video.paused) {
  6. video.pause();
  7. isPaused = true;
  8. } else if (isPaused) {
  9. video.play();
  10. isPaused=false;
  11. }
  12. });
  13. }, {threshold: 1});
  14. observer.observe(video);

上面代码中,IntersectionObserver()的第二个参数是配置对象,它的threshold属性等于1,即目标元素完全可见时触发回调函数。