Javascript getBoundingClientRect()更改的事件或观察者
是否有一种方法可以检测元素的Javascript getBoundingClientRect()更改的事件或观察者,javascript,dom,mutation-observers,dom-events,getboundingclientrect,Javascript,Dom,Mutation Observers,Dom Events,Getboundingclientrect,是否有一种方法可以检测元素的getBoundingClientRect()矩形何时发生了更改,而不实际计算getBoundingClientRect()?像“脏旗”之类的东西?天真地说,我假设在浏览器的内部工作中一定有这样一种机制,但我还没有发现domapi中公开了这种机制。也许有一种方法可以通过变异观察者做到这一点 我的应用程序是一个web组件,它将DOM元素转换为图形的节点,并将边绘制到全屏画布上。看 现在,我正在为每个元素调用getBoundingClientRect(),每个动画帧调用一
getBoundingClientRect()
矩形何时发生了更改,而不实际计算getBoundingClientRect()
?像“脏旗”之类的东西?天真地说,我假设在浏览器的内部工作中一定有这样一种机制,但我还没有发现domapi中公开了这种机制。也许有一种方法可以通过变异观察者做到这一点
我的应用程序是一个web组件,它将DOM元素转换为图形的节点,并将边绘制到全屏画布上。看
现在,我正在为每个元素调用getBoundingClientRect()
,每个动画帧调用一次,即使没有任何变化。感觉很贵。我通常在一台功能相当强大的计算机上以每秒60帧的速度获得%15-%50的CPU使用率
有人知道这样的事吗?你认为这样的期望合理吗?这种事情可行吗?以前有人提出过吗?如上述评论所述。您正在寻找的API是:
ResizeObserver
和IntersectionObserver
。但是,有几件事需要注意:
仅当观察到的元素更改大小时才会激发。它基本上只会给你正确的宽度和高度值ResizeObserver
和ResizeObserver
都不应该阻止绘制IntersectionObserver
将在布局之后但在绘制之前触发,这本质上使其感觉同步ResizeObserver
异步激发IntersectionObserver
IntersectionObserver
的用途。它通常可用于可见性检测。这里的问题是,IntersectionObserver
仅在交叉点比率发生变化时才会触发。这意味着,如果一个较小的子对象在一个较大的容器div中移动,并且您跟踪父对象和子对象之间的交集,那么您将不会得到任何事件,除非该子对象正在进入或退出父对象
您仍然可以跟踪元素何时移动。这就是为什么:
- 首先,使用
测量要跟踪的元素的位置getBoundingClientRect
- 插入一个div作为body的绝对定位的直接子对象,该子对象正好位于被跟踪元素所在的位置
- 开始跟踪此div与原始图元之间的交点
- 十字路口应该从1点开始。当它改变为其他内容时:
- 使用
重新测量元素getBoundingClientRect
- 触发位置/大小更改事件
- 将自定义div的样式更新到元素的新位置
- 观察者应再次开火,且交叉比再次为1,此值可忽略
- 使用
注:此技术也可用于更有效的polypill for
ResizeObserver
,这是比IntersectionObserver
更新的功能。通常可用的PolyFill依赖于MutationObserver
,后者的效率要低得多。您正在寻找的。另请参见。@wOxxOm-wow。。。显然这是最前沿的东西!它不会检测到重新定位。在拖动元素的情况下,如果可以确保父元素未移动/调整大小,则只需使用offsetLeft和offsetTop。我的意思是,您可以只计算一次父元素的位置,然后使用子元素的offsetLeft和offsetTop。并考虑window.scrollX&Y.@wOxxOm,您是否建议对父对象执行getBoundingClientRect(),然后对父对象的子对象使用offsetLeft和offsetTop?我认为这对相对定位的孩子来说是个好主意,但在这种情况下,我绝对定位了孩子。你的方法听起来确实更有效,但它太复杂了,不可能是一个通用的解决方案。你有你的方法的例子吗?考虑到绝对定位元素是身体的直接子元素,但IntersectionObserver会要求它是我们想要的元素的后代,我看不出这是如何工作的track@MarcS如果被跟踪元素没有位置:相对
,则绝对定位的子元素将相对定位有些祖先确实有位置:相对的代码>。我认为被跟踪的元素需要两个绝对定位的子元素(一个在左上角,另一个在右下角)才能工作(如果它只在左上角,那么如果被跟踪的元素向左移动1px,那么交叉点观察者就不会开火。你会怎么做“开始跟踪此div和原始元素之间的交集。”步骤?对于传统的IntersectionObserver
,这似乎不可能,因为两个元素都不是另一个元素的祖先。