在前端开发中,无限列表是一个常见的实现场景。在展示商品的时候,因为需要去做一些打点和曝光之类的统计,需要知道每个商品是否有出现列表可视化区域。如果用常规的js去做,会用到大量的计算,但是如果用IntersectionObserver去做的话,只需要给每个item注册下,并提供一个满足触发条件时,需要执行的回调函数就可以了。

具体使用方法:

  1. 创建一个 IntersectionObserver对象。

    1
    2
    3
    4
    5
    const io = new IntersectionObserver(callback, {
    root: document.querySelector('#rootElement'),
    rootMargin: '1000px',
    threshold: 0.75
    })

    root是根元素,如果目标元素与根元素相交,就会触发回调

    rootMargin可以将根元素的作用扩大或缩小,采用的是元素margin的用法

    threshold是当目标元素与根元素相交多少比例的时候,触发回调函数。可以是一个0-1之间的数字,也可以是一个由一个数组。如果是数组,比如[0, 0.25, 0.5, 0.75, 1]那么就在目标元素与根元素刚相交,相交比例在0.25、0.5、0.75、1时,分别调用一次回调函数。

  2. 监听目标函数

    1
    2
    // 监听目标元素
    io.observe(document.querySelector('#targetElement'));

    监听目标函数的时候会执行一次无条件执行一次callback,如果是一组目标函数,则会放在一起执行。entries的数组存放的是同一事件循环中所有执行被监听的目标元素。

    此外,io还有一些其他的API

    1
    2
    3
    4
    // 取消监听目标元素
    io.unobserve(document.querySelector('#targetElement'));
    // 关闭监听器
    io.disconnect();
  3. 触发回调,给回调函数传参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // 回调函数接收两个参数
    // entries是所有被监听的目标元素组成的数组
    // observe是1.中创建的IntersectionObserver对象io
    function callback (entries, observer) {
    console.log(entries.length);

    entries.forEach(entry => {
    console.log('无条件触发');

    if (entry.intersectionRatio >= 0.75) {
    console.log('满足条件触发')
    observer.unobserve(entry.target);
    }
    })
    }
  4. entries中属性及其含义

    在3.中,我们从entry中拿到了一个intersectionRatio的值。表示的是触发时,目标元素与根元素的相交的比例。其实,entry对象中还有其他的信息,具体可以参考MDN:https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserverEntry中的讲述。

具体实例:https://gist.github.com/baiai/9c27f983a74772197b39eeedab44aacc