Как мне узнать фактическую ширину и высоту HTML-элемента?


896

Предположим, что у меня есть объект, <div>который я хочу центрировать на дисплее браузера (область просмотра). Для этого мне нужно рассчитать ширину и высоту <div>элемента.

Что я должен использовать? Пожалуйста, включите информацию о совместимости браузера.


9
Помните, что получение высоты элемента с помощью любого метода всегда влияет на производительность, поскольку браузер пересчитывает положение всех элементов на странице (перекомпоновка). Поэтому избегайте делать это слишком много. Изучите этот список, чтобы узнать, какие вещи вызывают перекомпоновку.
Марсело Лазарони

Ответы:


1291

Вы должны использовать .offsetWidthи .offsetHeightсвойства. Обратите внимание, что они принадлежат элементу, а не .style.

var width = document.getElementById('foo').offsetWidth;

Функция.getBoundingClientRect() возвращает размеры и расположение элемента в виде чисел с плавающей точкой после выполнения CSS-преобразований.

> console.log(document.getElementById('id').getBoundingClientRect())
DOMRect {
    bottom: 177,
    height: 54.7,
    left: 278.5,​
    right: 909.5,
    top: 122.3,
    width: 631,
    x: 278.5,
    y: 122.3,
}

174
Осторожно! offsetHeight / offsetWidth может вернуть 0, если вы недавно выполнили определенные модификации DOM для элемента. Возможно, вам придется вызывать этот код в вызове setTimeout после изменения элемента.
Дан Фабулич

37
Документация о .offsetWidthand .offsetHeight: developer.mozilla.org/en/Determining_the_dimensions_of_elements
Денилсон Са Майя

31
При каких обстоятельствах он возвращает 0?
Гепард

46
@JDandChips: offsetWidthбудет 0, если элемент равен display:none, в то время как вычисленное widthможет все еще иметь положительное значение в этом случае. visibility:hiddenне влияет на offsetWidth.
MrWhite

21
@Supuhstar оба имеют разные значения. offsetWidthвозвращает «целое» поле, включая содержимое, отступы и границы; while clientWidthвозвращает размер только поля содержимого (поэтому оно будет иметь меньшее значение всякий раз, когда элемент имеет ненулевое заполнение и / или границу). (мод отредактирован для ясности)
Edurne Pascual

200

Взгляни на Element.getBoundingClientRect() .

Этот метод возвращает объект , содержащий width, heightи некоторые другие полезные значения:

{
    width: 960,
    height: 71,
    top: 603,
    bottom: 674,
    left: 360,
    right: 1320
}

Например:

var element = document.getElementById('foo');
var positionInfo = element.getBoundingClientRect();
var height = positionInfo.height;
var width = positionInfo.width;

Я считаю, что это не имеет проблемы, которые .offsetWidthи .offsetHeightделают, где они иногда возвращаются 0(как обсуждено в комментариях здесь )

Другое отличие getBoundingClientRect()может возвращать дробные пиксели, где .offsetWidthи .offsetHeightбудет округлять до ближайшего целого числа.

Примечание IE8 : getBoundingClientRectне возвращает высоту и ширину в IE8 и ниже. *

Если вы должны поддерживать IE8, используйте .offsetWidthи .offsetHeight:

var height = element.offsetHeight;
var width = element.offsetWidth;

Стоит отметить, что объект, возвращаемый этим методом, на самом деле не является нормальным объектом. Его свойства не перечисляются (например, Object.keysне работают "из коробки").

Подробнее об этом здесь: Как лучше всего преобразовать ClientRect / DomRect в простой объект

Ссылка:


8
getboundingClientRect () вернет фактическую ширину и высоту элементов, масштабированных через css, тогда как offsetHeightи offsetWidthне будет.
Люк

66

ПРИМЕЧАНИЕ : этот ответ был написан в 2008 году. В то время лучшим кросс-браузерным решением для большинства людей было использование jQuery. Я оставляю здесь ответ для потомков, и, если вы используете jQuery, это хороший способ сделать это. Если вы используете какой-то другой фреймворк или чистый JavaScript, принятый ответ, вероятно, будет правильным решением.

Начиная с jQuery 1.2.6 вы можете использовать одну из основных функций CSS , heightи width(или, outerHeightи outerWidth, в зависимости от обстоятельств).

var height = $("#myDiv").height();
var width = $("#myDiv").width();

var docHeight = $(document).height();
var docWidth = $(document).width();

45

На всякий случай, если это кому-нибудь пригодится, я помещаю текстовое поле, кнопку и div все с одним и тем же css:

width:200px;
height:20px;
border:solid 1px #000;
padding:2px;

<input id="t" type="text" />
<input id="b" type="button" />
<div   id="d"></div>

Я пробовал это в chrome, firefox и ie-edge, я пробовал с jquery и без, и я пробовал с и без box-sizing:border-box. Всегда с<!DOCTYPE html>

Результаты:

                                                               Firefox       Chrome        IE-Edge    
                                                              with   w/o    with   w/o    with   w/o     box-sizing

$("#t").width()                                               194    200    194    200    194    200
$("#b").width()                                               194    194    194    194    194    194
$("#d").width()                                               194    200    194    200    194    200

$("#t").outerWidth()                                          200    206    200    206    200    206
$("#b").outerWidth()                                          200    200    200    200    200    200
$("#d").outerWidth()                                          200    206    200    206    200    206

$("#t").innerWidth()                                          198    204    198    204    198    204
$("#b").innerWidth()                                          198    198    198    198    198    198
$("#d").innerWidth()                                          198    204    198    204    198    204

$("#t").css('width')                                          200px  200px  200px  200px  200px  200px
$("#b").css('width')                                          200px  200px  200px  200px  200px  200px
$("#d").css('width')                                          200px  200px  200px  200px  200px  200px

$("#t").css('border-left-width')                              1px    1px    1px    1px    1px    1px
$("#b").css('border-left-width')                              1px    1px    1px    1px    1px    1px
$("#d").css('border-left-width')                              1px    1px    1px    1px    1px    1px

$("#t").css('padding-left')                                   2px    2px    2px    2px    2px    2px
$("#b").css('padding-left')                                   2px    2px    2px    2px    2px    2px
$("#d").css('padding-left')                                   2px    2px    2px    2px    2px    2px

document.getElementById("t").getBoundingClientRect().width    200    206    200    206    200    206
document.getElementById("b").getBoundingClientRect().width    200    200    200    200    200    200
document.getElementById("d").getBoundingClientRect().width    200    206    200    206    200    206

document.getElementById("t").offsetWidth                      200    206    200    206    200    206
document.getElementById("b").offsetWidth                      200    200    200    200    200    200
document.getElementById("d").offsetWidth                      200    206    200    206    200    206

1
Просто чтобы прояснить ... любой из этих браузеров делает что-то отличное от другого? Я не могу найти каких - либо различий ... Кроме того , я не вниз голосования (пока), но это не очень прямо ответить на вопрос, хотя он может быть легко Editted сделать это.
Зак Лисобей

1
Не был нацелен на то, чтобы ответить на вопрос - его уже ответили. Просто некоторая полезная информация и да, все основные браузеры последних версий согласны с этими значениями - и это хорошо.
Грэм

3
Ну ... если ваше намерение не состоит в том, чтобы ответить на вопрос, то это не относится к этому вопросу (как «ответ»). Я хотел бы рассмотреть возможность размещения этого на каком-либо внешнем ресурсе (возможно, в GitHub или в блоге) и связать его в комментарии к исходному Вопросу или одному из ответов.
Зак Лисобей

21
@ZachLysobey Есть исключения из каждого правила - и это здорово, полезно посмотреть.
Дэн Ниссенбаум

16

Согласно MDN: определение размеров элементов

offsetWidthи offsetHeightвозвращает «общий объем пространства, занимаемого элементом, включая ширину видимого содержимого, полосы прокрутки (если есть), отступы и границы»

clientWidthи clientHeightвозвращает «сколько места занимает фактически отображаемое содержимое, включая отступы, но не включая границы, поля или полосы прокрутки»

scrollWidthи scrollHeightвернуть «фактический размер контента, независимо от того, сколько его видно в данный момент»

Таким образом, это зависит от того, ожидается ли, что измеренное содержимое выйдет за пределы текущей видимой области.


5

Вам нужно только рассчитать его для IE7 и старше (и только если ваш контент не имеет фиксированного размера). Я предлагаю использовать условные комментарии HTML, чтобы ограничить взлом старых IE, которые не поддерживают CSS2. Для всех других браузеров используйте это:

<style type="text/css">
    html,body {display:table; height:100%;width:100%;margin:0;padding:0;}
    body {display:table-cell; vertical-align:middle;}
    div {display:table; margin:0 auto; background:red;}
</style>
<body><div>test<br>test</div></body>

Это идеальное решение. Это центрирует <div>любой размер, и сокращает это к размеру его содержания.


3

Легко изменить стили элементов, но довольно сложно прочитать значение.

JavaScript не может читать никакое свойство стиля элемента (elem.style), исходящее из css (внутреннее / внешнее), если вы не используете вызов встроенного метода getComputedStyle в javascript.

getComputedStyle (element [, pseudo])

Элемент: элемент для чтения значения.
псевдо: псевдоэлемент, если требуется, например, :: before. Пустая строка или отсутствие аргумента означает сам элемент.

В результате получается объект со свойствами стиля, например, elem.style, но теперь по отношению ко всем классам CSS.

Например, здесь стиль не видит границы:

<head>
  <style> body { color: red; margin: 5px } </style>
</head>
<body>

  <script>
    let computedStyle = getComputedStyle(document.body);

    // now we can read the margin and the color from it

    alert( computedStyle.marginTop ); // 5px
    alert( computedStyle.color ); // rgb(255, 0, 0)
  </script>

</body>

Поэтому изменил ваш код javaScript, включив в него getComputedStyle элемента, для которого вы хотите получить его ширину / высоту или другой атрибут

window.onload = function() {

    var test = document.getElementById("test");
    test.addEventListener("click", select);


    function select(e) {                                  
        var elementID = e.target.id;
        var element = document.getElementById(elementID);
        let computedStyle = getComputedStyle(element);
        var width = computedStyle.width;
        console.log(element);
        console.log(width);
    }

}

Вычисленные и разрешенные значения

В CSS есть две концепции:

Вычисленное значение стиля - это значение после применения всех правил CSS и наследования CSS в результате каскада CSS. Это может выглядеть как высота: 1em или размер шрифта: 125%.

Разрешенное значение стиля - это то, которое окончательно применяется к элементу. Значения, такие как 1em или 125%, являются относительными. Браузер принимает вычисленное значение и делает все единицы фиксированными и абсолютными, например: height: 20px или font-size: 16px. Для свойств геометрии разрешенные значения могут иметь плавающую точку, например, ширину: 50,5 пикселей.

Давным-давно getComputedStyle был создан для получения вычисляемых значений, но оказалось, что разрешенные значения намного удобнее, и стандарт изменился.
Так что в настоящее время getComputedStyle фактически возвращает разрешенное значение свойства.

Пожалуйста, обратите внимание:

getComputedStyle требует полного имени свойства

Вы всегда должны запрашивать точное свойство, которое вы хотите, например paddingLeft или высоту или ширину. В противном случае правильный результат не гарантируется.

Например, если есть свойства paddingLeft / paddingTop, то что мы должны получить для getComputedStyle (elem) .padding? Ничего, или, может быть, «сгенерированное» значение из известных отступов? Здесь нет стандартного правила.

Есть и другие несоответствия. Например, некоторые браузеры (Chrome) показывают 10px в документе ниже, а некоторые из них (Firefox) - нет:

<style>
  body {
    margin: 30px;
    height: 900px;
  }
</style>
<script>
  let style = getComputedStyle(document.body);
  alert(style.margin); // empty string in Firefox
</script>

для получения дополнительной информации https://javascript.info/styles-and-classes


1

element.offsetWidth и element.offsetHeight должны делать, как предложено в предыдущем посте.

Однако, если вы просто хотите центрировать контент, есть лучший способ сделать это. Предполагая, что вы используете xhtml строгий DOCTYPE. установите поле: 0, свойство auto и необходимую ширину в пикселях для тега body. Контент выравнивается по центру страницы.


1
Я думаю, что он тоже хочет отцентрировать его по вертикали, что является правильным испытанием для CSS, если вы не соответствуете определенным критериям (например, контент известного размера)
Грег

1

... кажется, CSS помогает поместить div в центр ...

<style>
 .monitor {
 position:fixed;/* ... absolute possible if on :root */
 top:0;bottom:0;right:0;left:0;
 visibility:hidden;
 }
 .wrapper {
 width:200px;/* this is size range */
 height:100px;
 position:absolute;
 left:50%;top:50%;
 visibility:hidden;
 }

 .content {
 position:absolute;
 width: 100%;height:100%;
 left:-50%;top:-50%;
 visibility:visible;
 }

</style>

 <div class="monitor">
  <div class="wrapper">
   <div class="content">

 ... so you hav div 200px*100px on center ...

  </div>
 </div>
</div>

0

Также вы можете использовать этот код:

var divID = document.getElementById("divid");

var h = divID.style.pixelHeight;

1
Хм, работает в Chrome и IE9, похоже, не работает в Firefox. Это работает только для определенных типов документов?
BrainSlugs83

1
pixelHeight был изобретением Internet Explorer, которое больше не должно использоваться stackoverflow.com/q/17405066/2194590
HolgerJeromin

0

если вам нужно центрировать его в порт дисплея браузера; Вы можете достичь этого только с помощью CSS

yourSelector {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
} 

-2

Вот код для WKWebView, который определяет высоту определенного элемента Dom (не работает должным образом для всей страницы)

let html = "<body><span id=\"spanEl\" style=\"font-family: '\(taskFont.fontName)'; font-size: \(taskFont.pointSize - 4.0)pt; color: rgb(\(red), \(blue), \(green))\">\(textValue)</span></body>"
webView.navigationDelegate = self
webView.loadHTMLString(taskHTML, baseURL: nil)

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    webView.evaluateJavaScript("document.getElementById(\"spanEl\").getBoundingClientRect().height;") { [weak self] (response, error) in
        if let nValue = response as? NSNumber {

        }
    }
}

просто чтобы быть ясно, это swiftкод iOS , верно? Не JavaScript. Я отказываюсь от понижения (т.к. это может быть довольно полезно), но учтите, что это не отвечает на вопрос и, скорее всего, будет более уместным по другому, специфичному для iOS вопросу. Если ничего еще не существует, возможно, подумайте над тем, чтобы задать вопрос и ответить на него.
Зак Лысобей

-3

Если offsetWidth возвращает 0, вы можете получить свойство width элемента style и найти его по номеру. "100px" -> 100

/\d*/.exec(MyElement.style.width)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.