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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32438642/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 15:16:52  来源:igfitidea点击:

clientWidth and clientHeight report zero while getBoundingClientRect is correct

javascripthtmlcss

提问by Motti

In MDN's description of Element.clientWidthit says.

在 MDN 的Element.clientWidth 描述中,它说。

Note:I've since updated MDN according to @potatopeelingsanswer.

注意:我已经根据@potatopeelings 的回答更新了 MDN 。

The Element.clientWidth property is the inner width of an element in pixels. 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.clientWidth 属性是元素的内部宽度(以像素为单位)。它包括填充但不包括垂直滚动条(如果存在,如果呈现)、边框或边距。

此属性会将值四舍五入为整数。如果需要小数值,请使用 element.getBoundingClientRect()。

From this I understand that other than rounding clientWidthshould be the same as getBoundingClientRect().width.

由此我明白除了四舍五入之外clientWidth应该与getBoundingClientRect().width.

However I see that for many elements (where displayis inline?) the clientWidth(and height) are zero, while the values returned by getBoundingClientRectseem correct.

但是我看到了很多的元素(其中displayinline?)的clientWidth(和高度)为零,而通过返回的值getBoundingClientRect似乎是正确的。

Searching on stackoverflow brings some answers saying that this happens before the document is in a readystate 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>

回答by potatopeelings

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:

1.If the element has no associated CSS layout box or if the CSS layout box is inline, return zero.
...

clientWidth 属性必须运行以下步骤:

1.如果元素没有关联的 CSS 布局框或者 CSS 布局框是内联的,则返回
...

回答by a better oliver

In addition to @potatopeelings's answer:

除了@potatopeelings 的回答:

Inline elements have no intrinsic or specified dimensions. E.g. you cannot define a width for a span(unless you change it's displayproperty).

内联元素没有内在或指定的维度。例如,您不能为 a 定义宽度span(除非您更改它的display属性)。

Also clientWidthand getBoundingClientRectserve different purposes and may return different values. The latter also considers transforms and returns the dimensions of an element as it is actually rendered.

并且clientWidthgetBoundingClientRect服务于不同的目的并且可能返回不同的值。后者还考虑变换并返回元素在实际渲染时的尺寸。

.class {
  transform: scale(0.5);
}

If clientWidthreturned 1000 in this case then the width of getBoundingClientRectwould be 500.

如果clientWidth在这种情况下返回 1000,则宽度getBoundingClientRect将为 500。

You can regard clientWidthas "how much space do I have available within the element" and getBoundingClientRectas "how much space does the element occupy on the screen". 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.

您可以将clientWidth“元素内有多少可用空间”getBoundingClientRect视为“元素在屏幕上占据多少空间”。所以在我们的例子中,元素将有足够的空间来并排包含两个 500 像素的元素,并且它会在屏幕上占据 500 像素。

回答by maioman

The returned value from getBoundingClientRect() is a DOMRect object which is the union of the rectangles returned by getClientRects() for the element ; 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).

getBoundingClientRect() 的返回值是一个 DOMRect 对象,它是 getClientRects() 为元素返回的矩形的联合;即使元素是内联的,此方法也会查看边界框尺寸(它没有对 clientWidth 具有的内联元素的限制 - 规格 @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-blockor block.

检查将显示属性更改为inline-block或时的差异block