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

mic*_*pes 12 javascript dom dom-events mutation-observers getboundingclientrect

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

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

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

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

Nam*_*oel 10

正如上面的评论中提到的。您正在寻找的 API 是:ResizeObserverIntersectionObserver。但是,有几点需要注意:

  • ResizeObserver只有当观察到的元素改变大小时才会触发。它基本上只会为您提供正确的宽度和高度值。
  • 双方ResizeObserverIntersectionObserver都应该不是块漆
  • ResizeObserver 将在布局之后但在绘制之前触发,这基本上使它感觉同步。
  • IntersectionObserver 异步触发。

如果您需要位置变化跟踪怎么办

这就是IntersectionObserver为此而生的。它通常可用于可见性检测。这里的问题是IntersectionObserver只有当相交的比率发生变化时才会触发。这意味着,如果一个小的孩子在一个较大的容器 div 内移动,并且您跟踪父级和子级之间的交集,除了当孩子进入或退出父级时,您将不会得到任何事件。

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

  • 首先使用 测量要跟踪的元素的位置getBoundingClientRect
  • 插入一个 div 作为 body 的绝对定位的直接子元素,它正好位于被跟踪元素所在的位置。
  • 开始跟踪这个 div 和原始元素之间的交集。
  • 交集应该从 1 开始。每当它变成其他东西时:
    • 使用 重新测量元素getBoundingClientRect
    • 触发位置/大小更改事件
    • 将自定义 div 的样式更新到元素的新位置。
    • 观察者应该再次以交集比为 1 再次触发,这个值可以忽略。

注意:此技术也可用于更高效的 p​​olypill,ResizeObserver其功能比IntersectionObserver. 常用的 polyfill 依赖于MutationObserver它的效率要低得多。

  • 你有你的方法的例子吗?我看不出这是如何工作的,因为绝对定位的元素是 body 的直接子元素,但 IntersectionObserver 要求它是我们想要跟踪的元素的后代 (10认同)
  • 被否决是因为 `IntersectionObserver` 只能观察子级与其祖先之间的交集,所以这个答案对于非祖先 div 来说是不正确的,就好像它是一个猜测一样。 (3认同)
  • 您将如何执行“开始跟踪此 div 和原始元素之间的交集”。步?对于传统的“IntersectionObserver”来说这似乎是不可能的,因为两个元素都不是另一个元素的祖先。 (2认同)