本文仍在修改和完善当中,如有疑问,可以评论和我互动。

Kico Style 内置了一个非常有用的新组件 - 图片懒加载,它是通过判断图片元素是否进入可视区域来确定是否开始加载图片的。我目前利用 windowscroll 事件来实现,它的原理是利用 EventListener 侦听页面滚动,当鼠标滚动一次(或触摸屏拖动一次)则自动执行一次指定的函数。

懒加载原理.jpg

在实际操作中,Scroll 事件触发太过频繁,很显然这样做浪费了一些不必要的性能。而我近期 Google 发现,有一套更加完善的 API 可以实现这个功能,它就是我们今天提到的 Intersection Observer 同学了。

兼容性

你也许会觉感到奇怪,为什么我称它为 “同学” 而不是 “先生”。这是因为 Intersection Observer 这套标准在 Chrome 51 上才正式被添加,可以看出它还很年轻,兼容性并不是非常好。但即便如此,它未来潜力依旧是无限的。

如果想知道它是否支持当前浏览器,你可以用 if 语句判断。

"IntersectionObserver" in window

开始使用

实例化一个 IntersectionObserver 对象以开始使用:

var obs = new IntersectionObserver(callback, option);

方法

IntersectionObserver 对象有如下方法:

  • disconnect() - 使 IntersectionObserver 对象停止监听工作。
  • observe() - 使 IntersectionObserver 开始监听一个目标元素。
  • takeRecords() - 返回所有观察目标的 IntersectionObserverEntry 数组对象。
  • unobserve() - 使 IntersectionObserver 停止监听特定目标元素。

参数

IntersectionObserver 对象的 callback 函数有一个参数,它返回了一个 IntersectionObserverEntry 数组对象,这里收集着所有待处理的对象,每个对象都有几个属性,它们的用途如下:

  • time - 发生变化所用的时间
  • target - 被观察元素
  • rootBounds - 当前窗口的宽高等信息
  • intersectionRatio - 被观察元素的可视比例
  • intersectionRect - 的可视比例
  • boundingClientRect - 与 getBoundingClientRect() 返回的结果是一样的

食用实例

懒加载

var obs = new IntersectionObserver(function (changes) {
    for(const item of changes) {
        // 如果可视区域大于 0,即在可视区域内
        if(item.intersectionRatio > 0){
            item.target.src = item.target.getAttribute("ks-original"); // 将 src 替换为 ks-original 字段的内容,开始加载图片
            obs.unobserve(item.target); // 取消侦听这个对象
        }
    }
});

var images = document.querySelectorAll("img");

// 遍历图片列表
images.forEach(function (item) {
    obs.observe(item); // 增加侦听对象
});

顶部菜单

无限滚动

参考资料

《IntersectionObserver》- MDN
《IntersectionObserver’s Coming into View》- Surma
《IntersectionObserver API 使用教程》- 阮一峰