Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/438.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript getBoundingClientRect()更改的事件或观察者_Javascript_Dom_Mutation Observers_Dom Events_Getboundingclientrect - Fatal编程技术网

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
,这似乎不可能,因为两个元素都不是另一个元素的祖先。