IntersectionObserver 监听元素是否出现或离开

2021-12-27  本文已影响0人  IamaStupid

IntersectionObserver 监听元素是否出现或离开可视区域, 实现图片懒加载

IntersectionObserver 这个 API,它是异步的,不会卡主线程,相比以前监听滚动事件计算可视区域的元素,更优秀,但是不兼容 IE,好在官方提供了 polyfill 来解决这个问题。详细地址:

https://github.com/w3c/IntersectionObserver/blob/main/polyfill/intersection-observer.js

// 下面是一个手机端vue项目的应用
// 用来懒加载图片,列表一次拉20条数据,但是数据中有大图片,
// 一次加载20张大图片很慢,所以把<li>中img设置成隐藏,
// 然后循环的时候,通过序号curTargetIndex来添加class,把隐藏的图片样式设置成block(这步其实可以不写,直接用v-if判断img是否出现)
// 实现图片懒加载,光是显示隐藏还不够,这个只是影响浏览器渲染
// 必须用用v-if判断是否插入img标签, 条件和通过序号curTargetIndex来添加class是一样的
// <img v-if="v-if="(index <= (activeIndex + 3) && index >= (activeIndex - 2))"" />

// vue 的 methods 方法
lazyLoadImg() {
      let _this = this
      function query(selector) {
        return Array.from(document.querySelectorAll(selector));
      }

      let allEntries = []
      var observer = new IntersectionObserver(
        function(entries) {
          // console.log('container entries ------', entries)
          // 第一次初始化,还没滚动页面的时候,会把observe监听的全部打印出来
          if (entries.length > 1) {
            entries.forEach((item) => {
              allEntries.push(item.target)
            })
          }
          if (entries[0].intersectionRatio <= 0) return;
          if (entries.length === 1) {
            // 获取出现在视窗里面的<li>的序号,通过这个序号,
            // 可以设置后面5个即将出现的 li.img-block  img{ display:block }
            _this.curTargetIndex = allEntries.indexOf(entries[0].target)
            console.log('Loaded new items', entries, _this.curTargetIndex);
          }
        },
        {
          // 如果这里不设置0.01触发事件(出现在视窗里),
          // 目标div出现在视窗后,打印的intersectionRatio 全是0
          threshold: [0.01],
          //  这个是滚动区域的id
          root: document.querySelector('#list1')
        }
      );

      query('.pcitem').forEach(function (item, i) {
        observer.observe(item);
      });
}
上一篇下一篇

猜你喜欢

热点阅读