1.Concepts&Usage

Intersection observer 允许你配置一个回调函数,每当targetelementviewport或者其他指定元素发生交集的时候该回调函数将会被执行。

设备视口或者其他元素我们称它为root element 或者 root。

特别是你想要监听(target)元素相对于浏览器视口(root)的交集变化的时候(intersection API初始化的时候 如果设置root参数为null或者不设置则root默认为设备视口)。

无论你是使用viewport或者其他element做为rootintersection API都会以相同方式工作,每当tartget elementroot中的可见性交集数量发生变化(target元素的位置在root中发生变化)都会执行你提供的回调函数。

target elementroot的相交程度我们用intersection ratio来描述。这个(intersection ratio)是一个关于target element相对于root的交集百分比的表述,它的取值在0.0和1.0之间。

示例,创建一个intersection observer

创建一个 IntersectionObserver对象并 传入相应参数和回调用函数,该回调函数将会在target 元素和root的交集大小超过threshold规定的大小时候被执行。

//book-codes/intersectionObserver/concepts&usage/1.js
var options = {
    root: document.querySelector('#scrollArea'), 
    rootMargin: '0px', 
    threshold: 1.0
}
var callback = function(entries, observer) { 
    /* Content excerpted, show below */ 
    console.log(entries)
};
var observer = new IntersectionObserver(callback, options);

这样我们就创建了一个observer,只需要调用他的方法,来observe一个DOM这样就可以了。 当 threshold 达到 1.0 的含义是当target元素完全出现在root元素(root参数指定的元素)里面的时候回调函数将会被执行。

Intersection observer options

  • root

    如果root参数指定为null或者不指定的时候默认使用浏览器视口做为root

  • rootMargin

    root元素的外边距。类似于css中的 margin 属性,比如 "10px 20px 30px 40px" (top, right, bottom, left)。如果有指定root参数,则rootMargin也可以使用百分比来取值。该属性值是用作root元素和target发生交集时候的计算交集的区域范围,使用该属性可以控制root元素每一边的收缩或者扩张。默认值为0。 如果想让root跟target提前相交,可以设置一个rootMargin来扩张root的范围。

  • threshold

    可以是单一的number也可以是number数组,target元素和root元素相交程度达到该值的时候IntersectionObserver注册的回调函数将会被执行。如果你只是想要探测当target元素的在root元素中的可见性超过50%的时候,你可以指定该属性值为0.5。如果你想要target元素在root元素的可见程度每多25%就执行一次回调,那么你可以指定一个数组[0, 0.25, 0.5, 0.75, 1]。默认值是0(意味着只要有一个target像素出现在root元素中,回调函数将会被执行)。该值为1.0含义是当target完全出现在root元素中时候 回调才会被执行。

Targeting an element to be observed

上面代码,我们创建了一个IntersectionObserver,下面我们为这个观察者配置一个目标(target)。

//book-codes/intersectionObserver/concepts&usage/1.js

var target = document.querySelector('.black');

observer.observe(target)

每当目标满足该IntersectionObserver指定的threshold值,回调被调用。

var callback = function (entries, observer) {
  /* Content excerpted, show below */
  entries.forEach(entry => {
    console.log(entry);
    console.log(entry.time); // a DOMHightResTimeStamp indicating when the intersection occurred.
    console.log(entry.rootBounds); // a DOMRectReadOnly for the intersection observer's root.
    console.log(entry.boundingClientRect); // a DOMRectReadOnly for the intersection observer's target.
    console.log(entry.intersectionRect); // a DOMRectReadOnly for the visible portion of the intersection observer's target.
    console.log(entry.intersectionRatio); // the number for the ratio of the intersectionRect to the boundingClientRect.
    console.log(entry.target); //the Element whose intersection with the intersection root changed.
  });

};

请留意,你注册的回调函数将会在主线程中被执行。所以该函数执行速度要尽可能的快。如果有一些耗时的操作需要执行,建议使用 Window.requestIdleCallback() 方法。

所有区域均被Intersection Observer API 当做一个矩形看待。如果元素是不规则的图形也将会被看成一个包含元素所有区域的最小矩形,相似的,如果元素发生的交集部分不是一个矩形,那么也会被看作是一个包含他所有交集区域的最小矩形。

这个有助于理解IntersectionObserverEntry 的属性,IntersectionObserverEntry用于描述target和root的交集。

代码中的entery就是一个IntersectionObserverEntry对象。

Last updated