简体   繁体   English

当getBoundingClientRect正确时,clientWidth和clientHeight报告为零

[英]clientWidth and clientHeight report zero while getBoundingClientRect is correct

In MDN's description of Element.clientWidth it says. 在MDN的Element.clientWidth描述中,它说。

Note: I've since updated MDN according to @potatopeelings answer. 注意:我已经根据@potatopeelings答案更新了MDN。

The Element.clientWidth property is the inner width of an element in pixels. Element.clientWidth属性是元素的内部宽度(以像素为单位)。 It includes padding but not the vertical scrollbar (if present, if rendered), border or margin. 它包括填充但不包括垂直滚动条(如果存在,如果呈现),边框或边距。

This property will round the value to an integer. 此属性将值舍入为整数。 If you need a fractional value, use element.getBoundingClientRect(). 如果需要小数值,请使用element.getBoundingClientRect()。

From this I understand that other than rounding clientWidth should be the same as getBoundingClientRect().width . 据我所知,除了舍入clientWidth应该与getBoundingClientRect().width

However I see that for many elements (where display is inline ?) the clientWidth (and height) are zero, while the values returned by getBoundingClientRect seem correct. 但是我看到对于许多元素( displayinline ?), clientWidth (和height)为零,而getBoundingClientRect返回的值似乎是正确的。

Searching on stackoverflow brings some answers saying that this happens before the document is in a ready state but I see this all the time, not just when the page is loading. 在stackoverflow上搜索会带来一些答案,说这是在文档处于就绪状态之前发生但我一直看到这一点,而不仅仅是在页面加载时。

This behaviour is consistent for all browsers I checked, where is it specified that this should be the behaviour? 这种行为对于我检查过的所有浏览器都是一致的,在哪里指定这应该是行为?

Sample: 样品:

 function str(name, width, height) { return name + ': (' + width + ', ' + height + ')'; } function test() { var s = document.getElementById('s'); var rect = s.getBoundingClientRect(); document.getElementById('out').innerHTML = str('client', s.clientWidth, s.clientHeight) + '<br/>' + str('bounding', rect.width, rect.height); } 
  <span id="s">A span</span><br/> <button onclick="test()">Test</button> <hr /> <div id="out"></div> 

From the spec ( http://www.w3.org/TR/cssom-view/#dom-element-clientwidth ) 来自规范( http://www.w3.org/TR/cssom-view/#dom-element-clientwidth

The clientWidth attribute must run these steps: clientWidth属性必须运行以下步骤:

1.If the element has no associated CSS layout box or if the CSS layout box is inline , return zero . 1.如果元素没有关联的CSS布局框, 或者CSS布局框是内联的 ,则返回
... ...

In addition to @potatopeelings's answer: 除了@ potatopeelings的回答:

Inline elements have no intrinsic or specified dimensions. 内联元素没有内在或指定的维度。 Eg you cannot define a width for a span (unless you change it's display property). 例如,您无法定义span的宽度(除非您更改其display属性)。

Also clientWidth and getBoundingClientRect serve different purposes and may return different values. clientWidthgetBoundingClientRect有不同的用途,可能会返回不同的值。 The latter also considers transforms and returns the dimensions of an element as it is actually rendered. 后者还会考虑变换并返回实际渲染时元素的尺寸。

.class {
  transform: scale(0.5);
}

If clientWidth returned 1000 in this case then the width of getBoundingClientRect would be 500. 如果clientWidth在这种情况下返回1000,那么getBoundingClientRect的宽度将为500。

You can regard clientWidth as "how much space do I have available within the element" and getBoundingClientRect as "how much space does the element occupy on the screen". 您可以将clientWidth视为“我在元素中有多少空间”,并将getBoundingClientRect视为“元素在屏幕上占用多少空间”。 So in our case the element would have enough space to contain two 500px elements side by side and it would occupy 500px on the screen. 所以在我们的例子中,元素将有足够的空间并排包含两个500px元素,它将在屏幕上占据500px。

The returned value from getBoundingClientRect() is a DOMRect object which is the union of the rectangles returned by getClientRects() for the element ; getBoundingClientRect()返回的值是一个DOMRect对象,它是getClientRects()为元素返回的矩形的并集; this method looks at the bounding box dimension even if the element is inline (it doesn't have the limit for inline elements clientWidth has - specs @potatopeelings links). 即使元素是内联的,此方法也会查看边界框维度(它没有内联元素clientWidth的限制 - specs @potatopeelings链接)。

 function str(name, width, height) { return name + ': (' + width + ', ' + height + ')'; } function test() { var s = document.getElementById('s'); var rect = s.getBoundingClientRect(); document.getElementById('out').innerHTML = str('client', s.clientWidth, s.clientHeight) + '<br/>' + str('bounding', rect.width, rect.height); } 
 #s{ display: inline-block } 
 <span id="s">A span</span><br/> <button onclick="test()">Test</button> <hr /> <div id="out"></div> 

check the difference when you change the display property to inline-block or block . 将display属性更改为inline-blockblock时检查差异。

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

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