简体   繁体   English

谁能解释 getBoundingClientRect() 的奇怪 Object 行为?

[英]Can anyone explain the strange Object behavior of getBoundingClientRect()?

If you test the following example you'll notice that the console does not log the correct coordinates, .onmouseover of the box.如果您测试以下示例,您会注意到控制台没有记录正确的坐标,即框的.onmouseover I know I'm getting the cb Object before the .onmouseover , but usually when you access a DOM Object property it gives you the correct value at the time.我知道我在 .onmouseover 之前获得了cb .onmouseover ,但通常当您访问 DOM Object 属性时,它会为您提供正确的值。

 var box = document.getElementById('box'), cb = box.getBoundingClientRect(); box.style.margin = '30px'; box.onmousemove = function(e){ console.log('x:'+(e.clientX-cb.left)+'; y:'+(e.clientY-cb.top)); }
 #box{ width:160px; height:90px; background:#700; }
 <div id='box'></div>

Notice this way works:注意这种方式有效:

 var box = document.getElementById('box'); box.style.margin = '30px'; box.onmousemove = function(e){ var cb = box.getBoundingClientRect(); console.log('x:'+(e.clientX-cb.left)+'; y:'+(e.clientY-cb.top)); }
 #box{ width:160px; height:90px; background:#700; }
 <div id='box'></div>

Well, it should work, oddly x never seems to hit 0 , either (of course I know I can do the math) .好吧,它应该可以工作,奇怪的是x似乎也从来没有达到0 (当然我知道我可以做数学) Is there any valid reason for any of the behavior I've described?我所描述的任何行为是否有任何正当理由? I'm using FireFox 69.0.3 (64-bit).我正在使用 FireFox 69.0.3(64 位)。 Is it a bug?它是一个错误吗? I have a work around.我有一个解决办法。 I'm just asking.我只是问问。

The issue is that in the first instance you take cb before adding the margin.问题是,在第一种情况下,您在添加边距之前先使用cb

Since getBoundingClientRect will give you the positions at the point of time it was called , you get a snapshot of the positions without a 30px offset.由于getBoundingClientRect在调用它的时间点为您提供位置,因此您将获得没有 30px 偏移的位置快照。 That's why both x and y never go below 30 in the first example but they do in the second when you get a fresh snapshot of the positions every time.这就是为什么xy在第一个示例中 go 永远不会低于30但在第二个示例中,当您每次都获得位置的新快照时它们会这样做。

If you you can get a reliable snapshot once, then the calculation would be correct:如果您可以获得一次可靠的快照,那么计算将是正确的:

 var box = document.getElementById('box'); box.style.margin = '30px'; var cb = box.getBoundingClientRect(); box.onmousemove = function(e){ console.log('x:'+(e.clientX-cb.left)+'; y:'+(e.clientY-cb.top)); }
 #box{ width:160px; height:90px; background:#700; }
 <div id='box'></div>

That's simply because a DOMRect is not live.这仅仅是因为 DOMRect 不存在。 That's just like a plain object that get created every time you call one of the methods that return such an object;这就像一个普通的 object 每次调用返回此类 object 的方法之一时都会创建; and even if the originating Element is modified, the DOMRect will still just be whatever it was when it got created.即使原始元素被修改,DOMRect 仍然是它创建时的样子。

 const target = document.getElementById( 'target' ); const rect_1 = target.getBoundingClientRect(); target.style.width = '120px'; const rect_2 = target.getBoundingClientRect(); console.log( rect_1.width, rect_2.width ); // 10, 120
 #target { width: 10px }
 <div id="target"></div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM