getBoundingClientRect()更改的事件或观察者

时间:2016-10-25 22:58:43

标签: javascript dom mutation-observers dom-events getboundingclientrect

有没有办法在没有实际计算getBoundingClientRect()的情况下检测元素的getBoundingClientRect()矩形何时发生了变化?像“脏旗”的东西?天真地,我认为在浏览器的内部工作中必须存在这样的机制,但是我无法在DOM API中发现这个事物。也许有办法用MutationObservers做到这一点?

我的应用程序是一个Web组件,它将DOM元素转换为图形的节点,并将边缘绘制到全屏画布上。请参阅here

现在,我正在为每个元素调用getBoundingClientRect(),每个动画帧帧调用一次,即使没有任何变化。这感觉很贵。我通常以60 fps的速度在功能强大的计算机上获得%15-%50的CPU使用率。

有谁知道这样的事情?你认为期待这样的事情是否合理?这种事情可行吗?以前有没有被提出过?

1 个答案:

答案 0 :(得分:4)

如以上评论中所述。您要查找的API是:ResizeObserverIntersectionObserver。但是,有几件事要注意:

  • ResizeObserver仅在观察到的元素更改大小时才会触发。实际上,它只会为您提供正确的宽度和高度值。
  • ResizeObserverIntersectionObserver都不会阻塞绘画,因此您不能依靠它们同步进行事件。认为它们更像是事后发出变更通知。

如果您需要位置更改跟踪怎么办

这就是IntersectionObserver的用途。它通常可用于可见性检测。这里的问题是IntersectionObserver仅在相交比例发生变化时才会触发。这意味着,如果一个小孩在较大的容器div中到处走动,并且跟踪父级与子级之间的交集,那么除非该子级进入或退出父级,否则您将不会获得任何事件。

您仍然可以跟踪元素何时移动。这是这样的:

  • 首先使用getBoundingClientRect测量要跟踪的元素的位置。
  • 将div插入为主体的绝对直接子代,该子代完全位于被跟踪元素所在的位置。
  • 开始跟踪此div与原始元素之间的交集。
  • 交叉点应从1开始。每当更改为其他东西时:
    • 使用getBoundingClientRect重新测量元素。
    • 触发位置/大小更改的事件
    • 将自定义div的样式更新为元素的新位置。
    • 观察者应该以1的相交比再次触发,此值可以忽略。

注意:此技术还可以用于ResizeObserver的更有效的多药丸,这是一种比IntersectionObserver更新的功能。常见的polyfill依赖MutationObserver,效率低得多。

相关问题