Intersection Observer API rootMargin 选项不生效的问题

本文不对 Intersection Observer API 的基础概念做详细说明,文中提到的 root 可以简单理解为容器元素,target 为监听元素。

当使用 Intersection Observer API 的 rootMargin 时,会遇到 rootMargin 不生效的情况,即交叉点仍然是 target rect 与 root rect,而预期的行为是交叉检测是 target rect 与 root rect + rootMargin。

造成这个问题的原因有可能是容器元素设置了 overflow 导致的,规范文档中提到:

Note: rootMargin only applies to the intersection root itself. If a target Element is clipped by an ancestor other than the intersection root, that clipping is unaffected by rootMargin.

这里有一个 Demo 模拟了 rootMargin 不生效的情况。

默认情况下,由于 html, body 设置了 overflow 导致 rootMargin 不生效,必须滚动到红色区域(即 target 元素)才会产生交叉:

当勾选 no overflow 时,会移除 html, body 的 overflow,这时无需滚动到红色区域即可产生交叉:

基于以上,在实际开发中如非必要,尽量不要在根元素或者应用的父容器中设置 overflow,当遇到需要在根元素设置 overflow 解决问题时,先想想有没有更好的解决方案,或者是写的代码本身有问题。

BTW:根元素中设置 height: 100% 也是不推荐的。

References

https://stackoverflow.com/a/58625634