TLDR: 使用 Intersection Observer 来观察元素的位置变化,无需监听滚动事件或连续轮询。
https://ajk-essential.github.io/Position-Observer/
https://github.com/AJK-Essential/Position-Observer
传统上,要观察元素何时在视口内移动,我们必须依靠监听 HTML 元素的父元素的滚动事件或使用连续轮询方法,例如使用 requestanimationframe。
这有效......但还可以更好...
因为监听滚动事件可能会导致性能延迟。
并且连续轮询始终在后台运行……即使目标元素没有移动,这也可能会增加 CPU 的负载。
所以,这是一种方法/实验,看看我们是否可以使用 Intersection Observer 来观察 html 元素的位置变化。
交叉观察器非常擅长报告目标元素是否确实与根元素相交。它们可以报告目标元素和根元素之间相交的分数变化,这种变化在目标元素移动时发生。
我们还可以通过修改 rootBounds 的边距来更改捕获窗口(rootbounds)的尺寸。
嗯…
所以我们的想法是使用捕获窗口紧紧包裹目标。这意味着当目标元素移动时,它会撞击捕获窗口并与之相交,因此 Intersection Observer 使用高阈值数组(从 0 到 1,以 1/1000 为单位)报告分钟交叉点。这意味着交集观察器报告目标和根(捕获窗口)之间交集区域每 1/1000 的变化
如果它完全移出捕获窗口(当相交比为 0 时会发生这种情况),那么我们再次将根(捕获窗口)的边距更改为新的目标位置周围。
这种方法效果很好,直到我遇到滚动情况,其中目标位于视觉视口尺寸内(屏幕内),但在视觉上隐藏,因为它隐藏在滚动上下文中。
在这种情况下,交叉点比率始终为 0,因为只有当目标位于可视区域内时才会报告交叉点。
为了解决这个问题,我采取的方法是这样的。
当报告相交比为 0 时...
交叉点观察器断开连接,然后使用新设置重新连接:
捕获窗口尺寸设为整个屏幕(即 root-margins 为 0)。
这个场景的回调是用另一种方法进行的,以便区分 rootbounds 是视觉视口的时刻和它正好在目标周围的时刻。
因此,当 Intersection Observer 现在报告任何小于 1 的交叉比时,我们不会执行任何操作。对于每一份报告,我们都会说立场发生了变化。
当比率变为1时,表示目标完全在可视区域内。在此期间,我们再次断开 Intersection Observer 的连接,并使用之前的回调方法再次与目标周围的更精细的窗口重新连接。
因此捕获窗口(rootBounds)最终在更精细的窗口和视觉视口之间循环。
是的。我在我的 Github 存储库 (https://github.com/AJK-Essential/Position-Observer) 中实现了与 PositionObserver 类相同的功能。这些文件位于 dist 文件夹内。这些文件可以下载。
然后
PositionObserver 类可以像这样导入:
import { PositionObserver } from "./position-observer.js";
然后创建此 PositionObserver 的实例,如下所示:
const positionObs = new PositionObserver(posObsCallback);
其中 posObsCallback 是接受以下类型的对象参数的任何函数:
{ x: number; y: number; target: HTMLElement | Element; outOfViewport: boolean; rootBounds: DOMRect | null; };
当positionObserver检测到位置变化时,这将作为回调被调用。参数:
到目前为止,positionObserver 已经设置完毕。现在要检测元素的位置变化,我们需要像这样观察它:
positionObs.observe(target);
其中 target 代表我们想要观察的实际元素。
要停止观察位置变化,我们可以这样使用它:
positionObs.disconnect()
您还可以访问 https://github.com/AJK-Essential/Position-Observer/blob/main/docs/target-scroll.html 并查看脚本部分以查看示例实现
我不知道。根据我的测试,它有效。可能有些情况下它可能不起作用......
我建议将其与监听滚动结合使用(并将其用作连续轮询的替代品),因为我观察到有时它在演示中滚动时会错过跟踪目标。
随意使用和测试此 Github 存储库中的代码
(https://github.com/AJK-Essential/Position-Observer),甚至可以私下修改它以适应您的项目/业务需求,或者如果您发现了错误并且也有解决方案。
希望这对您有所帮助!
以上是使用 Intersection Observer 观察 HTML 元素的位置变化的详细内容。更多信息请关注PHP中文网其他相关文章!