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

时间:2015-09-07 12:20:05

标签: javascript html css

在MDN的description of Element.clientWidth中说。

<子> 注意:我已根据@potatopeelings答案更新了MDN。

  

Element.clientWidth属性是元素的内部宽度(以像素为单位)。它包括填充但不包括垂直滚动条(如果存在,如果呈现),边框或边距。

     
    

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

  

据我所知,除了舍入clientWidth之外,我应该与getBoundingClientRect().width相同。

但是我看到许多元素(displayinline?)clientWidth(和高度)为零,而getBoundingClientRect返回的值似乎正确

在stackoverflow上搜索会得到一些答案,说明在文档处于 ready 状态之前会发生这种情况,但我一直看到这种情况,而不仅仅是在页面加载时。

此行为对我检查的所有浏览器都是一致的,在哪里指定这应该是行为?

示例:

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>

3 个答案:

答案 0 :(得分:17)

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

  

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

     

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

答案 1 :(得分:12)

除了@ potatopeelings的回答:

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

同样clientWidthgetBoundingClientRect用于不同的目的,可能会返回不同的值。后者还会考虑变换并返回实际渲染时元素的尺寸。

.class {
  transform: scale(0.5);
}

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

您可以将clientWidth视为&#34;我在元素中有多少空间&#34;和getBoundingClientRect as&#34;元素在屏幕上占用多少空间&#34;。所以在我们的例子中,元素将有足够的空间并排包含两个500px元素,它将在屏幕上占据500px。

答案 2 :(得分:0)

getBoundingClientRect()返回的值是一个DOMRect对象,它是getClientRects()为元素返回的矩形的并集;即使元素是内联的,此方法也会查看边界框维度(它没有内联元素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>

在将显示属性更改为inline-blockblock时检查区别。