clientWidth и clientHeight сообщают ноль, в то время как getBoundingClientRect является правильным
В описании MDN Element.clientWidth это говорит.
Примечание: с тех пор я обновил MDN в соответствии с ответом potatopeelings.
Свойство Element.clientWidth является внутренней шириной элемента в пикселях. Он включает отступы, но не вертикальную полосу прокрутки (если присутствует, если отображается), границу или поле.
Это свойство округляет значение до целого числа. Если вам нужно дробное значение, используйте element.getBoundingClientRect().
Из этого я понимаю, что кроме округления clientWidth
должен быть таким же, как getBoundingClientRect().width
,
Однако я вижу, что для многих элементов (где display
является inline
?) clientWidth
(и высота) равны нулю, а значения, возвращаемые getBoundingClientRect
кажется правильным.
Поиск в stackru приносит некоторые ответы о том, что это происходит до того, как документ находится в состоянии готовности, но я вижу это постоянно, а не только при загрузке страницы.
Это поведение одинаково для всех браузеров, которые я проверял. Где указано, что это должно быть поведение?
Образец:
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 ответа
Из спецификации ( http://www.w3.org/TR/cssom-view/)
Атрибут clientWidth должен выполнить эти шаги:
1.Если элемент не имеет связанного блока макета CSS или если блок макета CSS встроен, верните ноль.
...
В дополнение к ответу @potatopeelings:
Встроенные элементы не имеют внутренних или указанных размеров. Например, вы не можете определить ширину для span
(если вы не измените это display
имущество).
Также clientWidth
а также getBoundingClientRect
служат различным целям и могут возвращать разные значения. Последний также учитывает преобразования и возвращает размеры элемента в том виде, как он фактически отображается.
.class {
transform: scale(0.5);
}
Если clientWidth
вернул 1000 в этом случае, то ширина getBoundingClientRect
будет 500.
Вы можете рассмотреть clientWidth
как "сколько места у меня есть в элементе" и getBoundingClientRect
как "сколько места элемент занимает на экране". Таким образом, в нашем случае элемент будет иметь достаточно места для размещения двух элементов размером 500 пикселей рядом, и он будет занимать 500 пикселей на экране.
Возвращаемое значение из getBoundingClientRect() является объектом DOMRect, который представляет собой объединение прямоугольников, возвращаемых getClientRects() для элемента; этот метод смотрит на размер ограничительной рамки, даже если элемент встроен (он не имеет ограничения для встроенных элементов, которые имеет clientWidth - specs @potatopeelings links).
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-block
или же block
,