Open jtwang7 opened 3 years ago
过去,要检测一个元素是否可见或者两个元素是否相交并不容易,很多解决办法不可靠或性能很差。然而,随着互联网的发展,这种需求却与日俱增,比如,下面这些情况都需要用到相交检测:
过去,相交检测通常要用到事件监听,并且需要频繁调用 Element.getBoundingClientRect() 方法以获取相关元素的边界信息。事件监听和调用 Element.getBoundingClientRect() 都是在主线程上运行,因此频繁触发、调用可能会造成性能问题。这种检测方法极其怪异且不优雅。 此外,不同第三方库实现自己的相交检测方法,会导致页面在滚动时不断触发各种回调。
Element.getBoundingClientRect()
假如有一个无限滚动的网页,开发者使用了一个第三方库来管理整个页面的广告,又用了另外一个库来实现消息盒子和点赞,并且页面有很多动画(译注:动画往往意味着较高的性能消耗)。两个库都有自己的相交检测程序,都运行在主线程里,而网站的开发者对这些库的内部实现知之甚少,所以并未意识到有什么问题。但当用户滚动页面时,这些相交检测程序就会在页面滚动回调函数里不停触发调用,造成性能问题,体验效果让人失望。
Intersection Observer API 提供了一种异步检测目标元素与祖先元素或 viewport 相交情况变化的方法。 Intersection Observer API 会注册一个回调函数,每当被监视的元素进入或者退出另外一个元素时(或者 viewport ),或者两个元素的相交部分大小发生变化时,执行注册的回调方法。网站的主线程不需要再为了监听元素相交而辛苦劳作,浏览器会自行优化元素相交管理。
注意 Intersection Observer API 无法提供重叠的像素个数或者具体哪个像素重叠,他的更常见的使用方式是——当两个元素相交比例在 N% 左右时,触发回调,以执行某些逻辑。
Intersection Observer API 允许你配置一个回调函数,当以下情况发生时会被调用:
无论您是使用视口还是其他元素作为根,API都以相同的方式工作,只要目标元素的可见性发生变化,就会执行您提供的回调函数,以便它与所需的交叉点交叉。
目标(target)元素与根(root)元素之间的交叉度是交叉比(intersection ratio)。这是目标(target)元素相对于根(root)的交集百分比的表示,它的取值在0.0和1.0之间。
IntersectionObserver() 创建一个新的 IntersectionObserver 对象,当其监听到目标元素的可见部分穿过了一个或多个阈(thresholds)时,会执行指定的回调函数。
当一个IntersectionObserver对象被创建时,其被配置为监听根中一段给定比例的可见区域。一旦IntersectionObserver被创建,则无法更改其配置,所以一个给定的观察者对象只能用来监听可见区域的特定变化值;然而,你可以在同一个观察者对象中配置监听多个目标元素。
"0px 0px 0px 0px"
IntersectionObserver API 并不会每次在元素的交集发生变化的时候都会执行回调。相反它使用了 thresholds 参数。当你创建一个 observer 的时候,你可以提供一个或者多个 number 类型的数值用来表示 target 元素在 root 元素的可见程序的百分比,然后,API的回调函数只会在元素达到 thresholds 规定的阈值时才会执行。例如,当你想要在 target 在 root 元素中中的可见性每超过25%或者减少25%的时候都通知一次。你可以在创建 observer 的时候指定 thresholds 属性值为 [0, 0.25, 0.5, 0.75, 1]
IntersectionObserverEntry 接口 (从属于 Intersection Observer API ) 描述了目标元素与其根元素容器在某一特定过渡时刻的交叉状态。 IntersectionObserverEntry 的实例作为 entries 参数被传递到一个 IntersectionObserver() 构造函数所注册的回调函数中; 除了从回调函数参数中获取之外, 这些对象就只能通过调用 IntersectionObserver.takeRecords() 来获取.
IntersectionObserver.takeRecords()
属性
与交叉状态相关的属性保存在 IntersectionObserverEntry 对象上,因此其实例化的 entry 参数也能访问到这些属性,进一步精确控制回调函数内部的行为逻辑。
向 IntersectionObserver 构造函数传入相应配置参数和回调函数,实例化一个 IntersectionObserver 对象。所注册的回调函数将会在目标(target)元素和根(root)元素的交集大小超过阈值(threshold)规定的大小时候被执行。
// 构造器配置项 let options = { root: document.querySelector('#scrollArea'), rootMargin: '0px', threshold: 1.0 } let observer = new IntersectionObserver(callback, options);
获得 observer 实例对象后需要给定目标元素(一个或多个)进行观察;
let target = document.querySelector('#listItem'); observer.observe(target);
每当目标满足该 IntersectionObserver 指定的 threshold 值,回调被调用。回调接收 所有被添加到观察队列中的目标元素的 IntersectionObserverEntry 实例对象 和 观察者实例对象:
let callback =(entries, observer) => { entries.forEach(entry => { // Each entry describes an intersection change for one observed target element: // entry.boundingClientRect // entry.intersectionRatio // entry.intersectionRect // entry.isIntersecting // entry.rootBounds // entry.target // entry.time }); };
前言
过去,要检测一个元素是否可见或者两个元素是否相交并不容易,很多解决办法不可靠或性能很差。然而,随着互联网的发展,这种需求却与日俱增,比如,下面这些情况都需要用到相交检测:
过去,相交检测通常要用到事件监听,并且需要频繁调用
Element.getBoundingClientRect()
方法以获取相关元素的边界信息。事件监听和调用Element.getBoundingClientRect()
都是在主线程上运行,因此频繁触发、调用可能会造成性能问题。这种检测方法极其怪异且不优雅。 此外,不同第三方库实现自己的相交检测方法,会导致页面在滚动时不断触发各种回调。Intersection Observer API 提供了一种异步检测目标元素与祖先元素或 viewport 相交情况变化的方法。 Intersection Observer API 会注册一个回调函数,每当被监视的元素进入或者退出另外一个元素时(或者 viewport ),或者两个元素的相交部分大小发生变化时,执行注册的回调方法。网站的主线程不需要再为了监听元素相交而辛苦劳作,浏览器会自行优化元素相交管理。
概念
Intersection Observer API 允许你配置一个回调函数,当以下情况发生时会被调用:
无论您是使用视口还是其他元素作为根,API都以相同的方式工作,只要目标元素的可见性发生变化,就会执行您提供的回调函数,以便它与所需的交叉点交叉。
目标(target)元素与根(root)元素之间的交叉度是交叉比(intersection ratio)。这是目标(target)元素相对于根(root)的交集百分比的表示,它的取值在0.0和1.0之间。
IntersectionObserver
构造器
IntersectionObserver() 创建一个新的 IntersectionObserver 对象,当其监听到目标元素的可见部分穿过了一个或多个阈(thresholds)时,会执行指定的回调函数。
属性
"0px 0px 0px 0px"
。方法
IntersectionObserverEntry
IntersectionObserverEntry 接口 (从属于 Intersection Observer API ) 描述了目标元素与其根元素容器在某一特定过渡时刻的交叉状态。 IntersectionObserverEntry 的实例作为 entries 参数被传递到一个 IntersectionObserver() 构造函数所注册的回调函数中; 除了从回调函数参数中获取之外, 这些对象就只能通过调用
IntersectionObserver.takeRecords()
来获取.属性
属性
用法
Step1. 实例化一个 intersection observer
向 IntersectionObserver 构造函数传入相应配置参数和回调函数,实例化一个 IntersectionObserver 对象。所注册的回调函数将会在目标(target)元素和根(root)元素的交集大小超过阈值(threshold)规定的大小时候被执行。
Step2. 添加观察对象
获得 observer 实例对象后需要给定目标元素(一个或多个)进行观察;
每当目标满足该 IntersectionObserver 指定的 threshold 值,回调被调用。回调接收 所有被添加到观察队列中的目标元素的 IntersectionObserverEntry 实例对象 和 观察者实例对象: