1. 介绍
Web 的传统位置计算机制依赖于对 DOM 状态的显式查询,而这些查询已知会导致(昂贵的)样式重新计算和布局,并且经常因为持续轮询这些信息而成为显著性能开销的来源。
一个依赖这些行为的常见实践体系已经发展起来,包括(但不限于):
-
构建自定义的 DOM 和数据的预加载和延迟加载。
-
实现数据绑定的高性能滚动列表,这些列表加载并渲染数据集的子集。这些列表是移动交互的核心习惯用法。
-
计算元素的可见性。特别是,广告网络现在要求报告广告的“可见性”以货币化展示次数。这导致许多网站滥用滚动处理程序(导致滚动时卡顿),同步布局调用回读(在 rAF 循环中导致不必要的关键工作),并且诉诸于计算“真正”元素可见性的奇异插件解决方案(伴随着插件架构的所有相关开销)。
这些用例有几个共同点:
-
它们可以表示为关于单个元素相对于某些其他元素(或全局视口)状态的被动“查询”。
-
它们不施加严格的延迟要求;也就是说,信息可以异步交付(例如,从另一个线程)而不会产生惩罚。
-
几乎所有现有 Web 平台功能组合对它们的支持都很差,尽管它们被广泛使用,但仍需开发者付出额外的努力。
一个显著的非目标是像素精确的关于实际显示内容的信息(在某些浏览器架构中,面对滤镜、WebGL 和其他功能时,获取这些信息可能相当困难)。在所有这些场景中,即使信息在稍微延迟的情况下交付,并且没有完美的合成结果数据,该信息仍然是有用的。
Intersection Observer API 通过为开发者提供一种新的方法来异步查询元素相对于其他元素或全局视口的位置,解决了上述问题。异步交付消除了昂贵的 DOM 和样式查询、持续轮询以及使用自定义插件的需求。通过消除这些方法的需求,它允许应用程序显著降低 CPU、GPU 和能量成本。
var observer= new IntersectionObserver( changes=> { for ( const changeof changes) { console. log( change. time); // 变更发生的时间戳 console. log( change. rootBounds); // 根的未剪裁区域 console. log( change. boundingClientRect); // target.getBoundingClientRect() console. log( change. intersectionRect); // boundingClientRect,由其包含块祖先剪裁并与 rootBounds 相交 console. log( change. intersectionRatio); // intersectionRect 面积与 boundingClientRect 面积的比率 console. log( change. target); // 元素 target } }, {}); // 观察特定目标元素的交集事件。 observer. observe( target); // 停止观察特定目标元素的交集事件。 observer. unobserve( target); // 停止观察所有目标元素的阈值事件。 observer. disconnect();
2. Intersection Observer
Intersection Observer API 使开发者能够理解 目标 DOM 元素相对于 交叉根 的可见性和位置。
2.1. IntersectionObserverCallback
callback =
IntersectionObserverCallback undefined (sequence <IntersectionObserverEntry >,
entries IntersectionObserver );
observer
当 目标 的与 交叉根 的交集发生变化时,将调用此回调,如 处理模型 所述。
2.2. IntersectionObserver 接口
IntersectionObserver
接口可用于观察 交叉根 和一个或多个 目标 Element
之间交集的变化。
交叉根 对于 IntersectionObserver
来说,是其 root
属性的值,如果属性为非 null
;否则,它是 顶级浏览上下文 的 document
节点,称为 隐式根。
具有非 null
的 IntersectionObserver
被称为 显式根观察者,并且它可以观察任何在 包含块链 中属于 root
的后代的 目标 Element
。具有
null
root
的 IntersectionObserver
被称为 隐式根观察者。隐式根观察者的有效 目标 包括在 顶级浏览上下文 中的任何 Element
,以及在属于
顶级浏览上下文 的 后代浏览上下文列表 的任何 嵌套浏览上下文 中的任何 Element
。
当处理 隐式根观察者 时,API 对目标的 相关设置对象 的 origin 是否与顶级 origin 是 同源域 进行了区分,称为 同源域目标;而与 跨源域目标 相反。显式根观察者 的任何 目标 也是 同源域目标,因为 目标 必须与 交叉根 位于相同的 文档 中。
注意: 在 MutationObserver
中,MutationObserverInit
选项传递给 observe()
方法,而在 IntersectionObserver
中,选项传递给构造函数。这是因为对于 MutationObserver,每个被观察的 Node
可能有不同的一组属性进行过滤。对于 IntersectionObserver
,开发者可以选择使用一个观察者来使用相同的选项集跟踪多个目标;或者,他们可以为每个跟踪的目标使用不同的观察者。对于每个
目标
提供 rootMargin
或 threshold
值似乎会引入更多的复杂性,而不会解决额外的用例。如果需要,将来可以提供每个 observe()
的选项。
[Exposed =Window ]interface {
IntersectionObserver (
constructor IntersectionObserverCallback ,
callback optional IntersectionObserverInit = {});
options readonly attribute (Element or Document )?root ;readonly attribute DOMString rootMargin ;readonly attribute DOMString scrollMargin ;readonly attribute FrozenArray <double >thresholds ;undefined observe (Element );
target undefined unobserve (Element );
target undefined disconnect ();sequence <IntersectionObserverEntry >takeRecords (); };
new IntersectionObserver(callback, options)
-
返回运行 初始化一个新的 IntersectionObserver 算法的结果,并提供 callback 和 options。
observe(target)
-
运行 观察一个目标元素 算法,并提供 this 和 target。
unobserve(target)
-
运行 取消观察目标元素 算法,并提供 this 和 target。
注意:
MutationObserver
不实现unobserve()
。 对于IntersectionObserver
,unobserve()
解决了懒加载用例。在 target 变得可见后,不需要继续跟踪它。要么disconnect()
所有 target 并observe()
剩余的,或者为每个 target 创建一个单独的IntersectionObserver
。 disconnect()
-
对于 this 的内部
[[ObservationTargets]]
槽中的每个 target:-
从 target 的内部
[[RegisteredIntersectionObservers]]
槽中移除IntersectionObserverRegistration
记录,其observer
属性等于 this。 -
从 this 的内部
[[ObservationTargets]]
槽中移除 target。
-
takeRecords()
-
-
让 queue 成为 this 的内部
[[QueuedEntries]]
槽的副本。 -
清除 this 的内部
[[QueuedEntries]]
槽。 -
返回 queue。
-
root
, 类型(Element 或 Document)
, 只读, 可为空-
提供给
IntersectionObserver
构造函数的root
,如果没有提供则为null
。 rootMargin
, 类型 DOMString, 只读-
应用于 根交叉矩形 的偏移量,有效地扩展或缩小用于计算交叉的框。这些偏移量仅在处理 同源域目标 时应用;对于 跨源域目标,它们将被忽略。
获取时,返回以空格分隔的序列化
[[rootMargin]]
的结果,其中像素长度序列化为数字值加 "px",百分比序列化为数字值加 "%”。请注意,这不保证与传递给IntersectionObserver
构造函数的 options.rootMargin
相同。如果没有传递给IntersectionObserver
构造函数的rootMargin
,则此属性的值为 "0px 0px 0px 0px"。 scrollMargin
, 类型 DOMString, 只读-
偏移量应用于从 交叉根 到 目标 路径上的 滚动端口,有效地扩展或缩小用于计算交叉的裁剪矩形。
获取时,返回以空格分隔的序列化
[[scrollMargin]]
的结果,其中像素长度序列化为数字值加 "px",百分比序列化为数字值加 "%”。请注意,这不保证与传递给IntersectionObserver
构造函数的 options.scrollMargin
相同。如果没有传递给IntersectionObserver
构造函数的scrollMargin
,则此属性的值为 "0px 0px 0px 0px"。 thresholds
, 类型 FrozenArray<double>, 只读-
阈值列表,按数值升序排序,每个阈值是观察目标的交叉面积与边界框面积的比率。当任何一个目标跨越这些阈值时,将生成通知。如果没有为
IntersectionObserver
构造函数提供 options.threshold
,或者序列为空,则此属性的值将为 [0]。
如果一个 Element
的计算样式具有 overflow 属性,使其内容被裁剪到元素的 填充边缘,则定义为具有 内容裁剪。
IntersectionObserver
的 根交叉矩形 是我们将用来检查目标的矩形。
- 如果
IntersectionObserver
是一个 隐式根观察者, - 它被视为根是 顶级浏览上下文 的
document
, 根据document
的以下规则处理。 - 如果 交叉根 是
document
, - 它的大小是
document
的 视口(请注意,此处理步骤只能在document
是 完全活跃 时才能到达)。 - 否则,如果 交叉根 具有 内容裁剪,
- 它是元素的 填充区域。
- 否则,
- 它是获取 边界框 的结果,适用于 交叉根。
当为 同源域目标 计算 根交叉矩形 时,
根据 IntersectionObserver
的
[[rootMargin]]
槽中的偏移量扩展矩形,
类似于 CSS 的 margin 属性,
四个值分别表示顶部、右侧、底部和左侧边缘的偏移量,
正长度表示向外偏移。
百分比相对于未稀释矩形的宽度进行解析。
注意: rootMargin
仅适用于 交叉根 本身。
如果一个 目标 Element
被除 交叉根 之外的祖先元素裁剪,则该裁剪不受 rootMargin
影响。
- 要 将滚动边距应用于滚动端口
-
为 滚动端口 计算交叉矩形时 为 同源域目标,根据
IntersectionObserver
的[[scrollMargin]]
槽中的偏移量扩展矩形,类似于 CSS 的 margin 属性,四个值分别表示顶部、右侧、底部和左侧边缘的偏移量,正长度表示向外偏移。百分比相对于未稀释矩形的宽度进行解析。这些偏移量仅在处理 同源域目标 时应用;对于 跨源域目标,它们将被忽略。
注意:
scrollMargin
影响 目标 的所有可滚动祖先的裁剪,直到并包括 交叉根。scrollMargin
和rootMargin
都应用于可滚动的 交叉根 矩形。
注意: 根交叉矩形 和 滚动端口 交叉矩形不受 捏合缩放 的影响,并将报告未调整的 视口,这与捏合缩放的意图(像放大镜一样操作而不是改变布局)一致。
要解析边距(根或滚动) 从输入字符串 marginString, 返回一个包含 4 个像素长度或百分比的列表, 或者失败:
-
解析组件值列表 marginString,将结果存储为 tokens。
-
从 tokens 中删除所有空白符。
-
如果 tokens 的长度大于 4,返回失败。
-
如果 tokens 中没有元素,将 tokens 设置为 ["0px"]。
-
替换 tokens 中的每个 token:
-
如果 token 是一个 <percentage> 令牌,将其替换为等效的百分比。
-
否则,返回失败。
-
如果 tokens 中有一个元素,向 tokens 添加三个该元素的副本。否则,如果 tokens 中有两个元素,分别添加每个元素的副本。否则,如果 tokens 中有三个元素,向 tokens 添加第二个元素的副本。
-
返回 tokens。
2.3. IntersectionObserverEntry 接口
[Exposed =Window ]interface {
IntersectionObserverEntry (
constructor IntersectionObserverEntryInit );
intersectionObserverEntryInit readonly attribute DOMHighResTimeStamp time ;readonly attribute DOMRectReadOnly ?rootBounds ;readonly attribute DOMRectReadOnly boundingClientRect ;readonly attribute DOMRectReadOnly intersectionRect ;readonly attribute boolean isIntersecting ;readonly attribute double intersectionRatio ;readonly attribute Element target ; };dictionary {
IntersectionObserverEntryInit required DOMHighResTimeStamp ;
time required DOMRectInit ?;
rootBounds required DOMRectInit ;
boundingClientRect required DOMRectInit ;
intersectionRect required boolean ;
isIntersecting required double ;
intersectionRatio required Element ; };
target
boundingClientRect
, 类型为 DOMRectReadOnly,只读-
通过获取边界框为
target
获得的DOMRectReadOnly
。 intersectionRect
, 类型为 DOMRectReadOnly,只读-
boundingClientRect
被target
的各个祖先元素的剪辑矩形(不包括root
)相交,且与 根交集矩形 相交。 该值表示在 根交集矩形 内实际可见的target
部分。 isIntersecting
, 类型为 boolean,只读-
当
target
与root
相交时返回 true,否则返回 false。 该标志使得可以区分IntersectionObserverEntry
发出从相交到不相交的过渡信号; 以及发出从不相交到相交但交集矩形面积为零(当边缘相邻或boundingClientRect
面积为零时)的过渡信号的IntersectionObserverEntry
。 intersectionRatio
, 类型为 double,只读-
如果
boundingClientRect
的面积不为零, 该值将是intersectionRect
面积与boundingClientRect
面积的比率。 否则,如果isIntersecting
为 true,则该值为 1, 如果为 false,则该值为 0。 rootBounds
, 类型为 DOMRectReadOnly,只读,nullable-
对于 同源域目标,该值将是 根交集矩形。 否则,该值为
null
。 注意,如果目标与 浏览上下文 中的 交集根 在不同的坐标系统中, 该值将与boundingClientRect
和intersectionRect
处于不同的坐标系统中。 target
, 类型为 Element,只读time
, 类型为 DOMHighResTimeStamp,只读-
该属性必须返回一个与生成通知的 IntersectionObserver 实例相关的全局对象的 时间原点 相对的
DOMHighResTimeStamp
,该时间戳对应于记录交集的时间。
2.4. IntersectionObserverInit 字典
dictionary { (
IntersectionObserverInit Element or Document )?root =null ;DOMString rootMargin = "0px";DOMString scrollMargin = "0px"; (double or sequence <double >)threshold = 0; };
root
, 类型为(Element 或 Document)
,可为空,默认为null
rootMargin
, 类型为 DOMString,默认值为"0px"
-
类似于 CSS 的 margin 属性, 这是一个由 1 到 4 个组件组成的字符串, 每个组件要么是 绝对长度,要么是百分比。
"5px" // 所有边距均设置为 5px "5px 10px" // 上下边距 = 5px,左右边距 = 10px "-10px 5px 8px" // 上边距 = -10px,左右边距 = 5px,下边距 = 8px "-10px -5px 5px 8px" // 上边距 = -10px,右边距 = -5px,下边距 = 5px,左边距 = 8px scrollMargin
, 类型为 DOMString,默认值为"0px"
-
类似于
rootMargin
, 这是一个由 1 到 4 个组件组成的字符串, 每个组件要么是 绝对长度,要么是百分比。参见上面的
rootMargin
示例。 threshold
, 类型为(double 或 sequence<double>)
,默认值为0
-
触发回调的阈值列表。当 intersectionRect 的面积从大于或等于任何阈值变为小于该阈值时,或者反之,都会调用回调。
阈值必须在 [0, 1.0] 范围内,并代表通过获取边界框为target生成的矩形区域的百分比。
注意: 0.0 实际上表示“任何非零像素数”。
3. 处理模型
本节概述了用户代理在实现Intersection Observer API 时必须采取的步骤。
3.1. 内部槽定义
3.1.1. 文档
每个document
都有一个IntersectionObserverTaskQueued标志,初始值为false。
3.1.2. 元素
Element
对象具有内部[[RegisteredIntersectionObservers]]
槽,初始化为空列表。
此列表包含IntersectionObserverRegistration
记录,
这些记录具有一个observer
属性,持有一个IntersectionObserver
对象,
一个previousThresholdIndex
属性,
其值在-1到观察者的thresholds
属性的长度之间(包括),以及一个previousIsIntersecting
属性,持有一个布尔值。
3.1.3. IntersectionObserver
IntersectionObserver
对象具有内部[[QueuedEntries]]
和[[ObservationTargets]]
槽,这些槽初始化为空列表,还有一个内部[[callback]]
槽
由IntersectionObserver(callback, options)
初始化。
它们还具有内部[[rootMargin]]
和[[scrollMargin]]
槽,它们是由四个像素长度或百分比组成的列表。
3.2. 算法
3.2.1. 初始化一个新的IntersectionObserver
要初始化一个新的IntersectionObserver,给定一个IntersectionObserverCallback
callback和一个IntersectionObserverInit
字典options,执行以下步骤:
-
令this为一个新的
IntersectionObserver
对象 -
将this的内部
[[callback]]
槽设置为callback。 -
尝试从options.
rootMargin
解析出一个margin。 如果返回了一个列表,将this的内部[[rootMargin]]
槽设置为该列表。 否则,抛出一个SyntaxError
异常。 -
尝试从options.
scrollMargin
解析出一个margin。 如果返回了一个列表,将this的内部[[scrollMargin]]
槽设置为该列表。 否则,抛出一个SyntaxError
异常。 -
令thresholds为与options.
threshold
等价的一个列表。 -
如果thresholds中的任何值小于0.0或大于1.0,抛出一个
RangeError
异常。 -
将thresholds按升序排序。
-
如果thresholds为空,则向thresholds中追加
0
。 -
thresholds
属性的getter将返回这个排序后的thresholds列表。 -
返回this。
3.2.2. 观察一个目标元素
要观察一个目标元素,给定一个IntersectionObserver
observer和一个Element
target,遵循以下步骤:
-
如果target在observer的内部
[[ObservationTargets]]
槽中, 则返回。 -
令intersectionObserverRegistration为一个
IntersectionObserverRegistration
记录, 该记录具有observer
属性,设置为observer,previousThresholdIndex
属性,设置为-1
, 和previousIsIntersecting
属性,设置为false
。 -
将intersectionObserverRegistration附加到target的内部
[[RegisteredIntersectionObservers]]
槽中。 -
将target添加到observer的内部
[[ObservationTargets]]
槽中。
3.2.3. 停止观察一个目标元素
要停止观察一个目标元素,给定一个IntersectionObserver
observer和一个Element
target,请执行以下步骤:
-
从target的内部
[[RegisteredIntersectionObservers]]
插槽中移除IntersectionObserverRegistration
记录,其observer
属性等于this(如果存在)。 -
从this的内部
[[ObservationTargets]]
插槽中移除target(如果存在)。
3.2.4. 排队一个 Intersection Observer 任务
IntersectionObserver 任务源是一个用于调度任务的任务源,用于§ 3.2.5 通知 Intersection Observers。
要为document
document排队一个Intersection Observer 任务,请执行以下步骤:
-
如果document的IntersectionObserverTaskQueued标志被设置为 true, 则返回。
-
将document的IntersectionObserverTaskQueued标志设置为 true。
-
排队一个任务到与
document
的事件循环关联的IntersectionObserver 任务源,以通知 Intersection Observers。
3.2.5. 通知 Intersection Observers
要通知
Intersection Observers为一个document
document,请执行以下步骤:
-
将document的IntersectionObserverTaskQueued标志设置为 false。
-
让notify list成为所有
IntersectionObserver
的列表,其root
位于document的 DOM 树中。 -
对于notify list中的每个
IntersectionObserver
对象observer,执行以下步骤:-
如果observer的内部
[[QueuedEntries]]
插槽为空, 继续。 -
让queue成为observer的内部
[[QueuedEntries]]
插槽的副本。 -
清空observer的内部
[[QueuedEntries]]
插槽。 -
让callback成为observer的内部
[[callback]]
插槽的值。 -
使用queue作为第一个参数,observer作为第二个参数, 并将observer作为回调的 this 值调用callback。 如果这引发了异常,请报告该异常。
-
3.2.6. 排队一个 IntersectionObserverEntry
要为一个IntersectionObserver
observer排队一个IntersectionObserverEntry,给定一个document
document;DOMHighResTimeStamp
time;DOMRect
们
rootBounds,boundingClientRect,intersectionRect,和
isIntersecting标志;
和一个Element
target,
请执行以下步骤:
-
构造一个
IntersectionObserverEntry
, 传入time,rootBounds,boundingClientRect, intersectionRect,isIntersecting,和target。 -
将其附加到observer的内部
[[QueuedEntries]]
插槽中。
3.2.7. 计算目标元素和根的相交部分
要计算目标target和相交根root之间的相交部分,请运行以下步骤:
-
让intersectionRect成为获取target的边界框的结果。
-
让container成为target的包含块。
-
当container不是root时:
-
如果container是嵌套浏览上下文的
文档
, 通过将其剪裁到该文档
的视口来更新intersectionRect,并更新container 为container的浏览上下文容器。 -
将intersectionRect映射到container的坐标空间。
-
如果 container 是一个 滚动容器,应用
IntersectionObserver
的[[scrollMargin]]
到 container 的剪裁矩形,如 应用滚动边距到滚动端口 中所述。 -
如果container有一个内容剪裁或一个 css 剪裁路径属性, 通过应用container的剪裁来更新intersectionRect。
-
如果container是浏览上下文的根元素, 更新container为该浏览上下文的
文档
; 否则,更新container为container的包含块。
-
-
将intersectionRect映射到root的坐标空间。
-
通过与根相交矩形相交来更新intersectionRect。
-
返回intersectionRect。
3.2.8. 运行更新相交观察步骤
要为文档document运行 更新相交观察步骤,给定一个时间戳time,请运行以下步骤:
-
让observer list成为所有
IntersectionObserver
的列表, 其root
在document的DOM树中。 对于顶级浏览上下文,这包括隐式根观察者。 -
对于observer list中的每个observer:
-
让rootBounds成为observer的根相交矩形。
-
对于observer的内部
[[ObservationTargets]]
插槽中的每个target,按照observe()
调用的顺序处理每个target:-
让:
-
thresholdIndex为0。
-
isIntersecting为false。
-
targetRect为一个
DOMRectReadOnly
,其x、 y、width和height设置为0。 -
intersectionRect为一个
DOMRectReadOnly
,其x、 y、width和height设置为0。
-
-
将targetRect设置为通过获取target的边界框获得的
DOMRectReadOnly
。 -
让targetArea为targetRect的面积。
-
让intersectionArea为intersectionRect的面积。
-
如果targetRect和rootBounds相交或边缘相邻,即使相交面积为零(因为rootBounds或targetRect的面积为零),让isIntersecting为true。
-
如果targetArea非零,让intersectionRatio为intersectionArea除以targetArea。 否则,如果isIntersecting为true,让intersectionRatio为
1
,如果isIntersecting为false,让intersectionRatio为0
。 -
将thresholdIndex设置为observer.
thresholds
中第一个值大于intersectionRatio的索引,或者如果intersectionRatio大于或等于observer.thresholds
中的最后一个条目,则为observer.thresholds
的长度。 -
让intersectionObserverRegistration成为target的内部
[[RegisteredIntersectionObservers]]
插槽中observer的observer
属性相等的IntersectionObserverRegistration
记录。 -
让previousThresholdIndex为intersectionObserverRegistration的
previousThresholdIndex
属性。 -
让previousIsIntersecting为intersectionObserverRegistration的
previousIsIntersecting
属性。 -
如果thresholdIndex不等于previousThresholdIndex,或isIntersecting不等于previousIsIntersecting,队列一个IntersectionObserverEntry,传入observer、time、rootBounds、targetRect、intersectionRect、isIntersecting和target。
-
将thresholdIndex赋值给intersectionObserverRegistration的
previousThresholdIndex
属性。 -
将isIntersecting赋值给intersectionObserverRegistration的
previousIsIntersecting
属性。
-
-
3.3. IntersectionObserver 生命周期
一个IntersectionObserver
将保持活动状态,直到以下两个条件都成立:
- 没有脚本引用观察者。
- 观察者没有观察任何目标。
一个IntersectionObserver
将继续观察目标,直到调用观察者的unobserve()
方法并以目标作为参数;或调用观察者的disconnect()
。
3.4. 外部规范集成
3.4.1. HTML 处理模型:事件循环
一个 Intersection Observer 处理步骤作为子步骤存在于 "更新渲染" 步骤中, 在HTML 事件循环处理模型中。
3.4.2. 等待初始 IntersectionObserver 目标
一个document
被认为有等待初始 IntersectionObserver 目标,如果
至少有一个IntersectionObserver
满足以下条件:
- observer的
root
在document中(对于顶级浏览上下文,这包括隐式根观察者)。 - observer在其
[[ObservationTargets]]
插槽中有至少一个target,该target尚未排队任何IntersectionObserverEntry
。
在HTML 事件循环处理模型中,在"更新渲染"步骤下,"不必要的渲染"步骤应修改为添加一个额外的 跳过渲染更新的要求:
- document没有等待初始 IntersectionObserver 目标。
4. 无障碍性考虑
本节为非规范性内容。
对于核心的 IntersectionObserver 规范(本文档),目前没有已知的无障碍性考虑。 然而,有一些相关的规范和提案利用并参考了本规范,这些规范可能有其自身的无障碍性考虑。特别是,HTML § 2.5.7 延迟加载属性和CSS 包含 2 § 4 完全隐藏元素内容:content-visibility 属性的规范可能会对HTML § 6.9 页面查找、HTML § 6.6.3 tabindex 属性和空间导航产生影响。
5. 隐私和安全
本节为非规范性内容。
与此 API 相关的主要隐私问题与它可能提供给在跨源 iframe 上下文中运行的代码的信息有关(即跨源域目标的情况)。尤其是:
-
对于暴露 iframe 是否在全局视口内的隐私影响,尚未达成普遍共识。
-
存在 API 可能被用来探测全局视口几何信息的风险,这可能被用来推测用户的硬件配置。禁用
rootMargin
和scrollMargin
的效果,以及抑制rootBounds
对于 跨域目标 的原因是为了防止此类探测。
值得注意的是,在IntersectionObserver
之前,网页开发者曾以非常巧妙(且恐怖)的方式使用其他 API 来获取IntersectionObserver
提供的信息。从实际操作的角度来看,该 API 并未揭示通过其他方式无法获得的任何信息。
另一个考虑因素是IntersectionObserver
使用DOMHighResTimeStamp
,
该属性本身具有隐私和安全方面的考虑。然而,IntersectionObserver
受时间相关攻击的可能性不大。时间戳最多每次渲染更新生成一次(见§ 3.4.1 HTML 处理模型:事件循环),
这对于通常的时间攻击来说太不频繁。
6. 国际化
本节为非规范性内容。
目前没有已知的国际化问题。
7. 致谢
特别感谢所有贡献者的技术投入和建议,这些建议促进了本规范的改进。