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



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


ПРИМЕЧАНИЕ: этот ответ был написан в 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();
Вам следует использовать свойства .offsetWidth и .offsetHeight.
Обратите внимание, что они принадлежат элементу, а не .style.
var width = document.getElementById('foo').offsetWidth;
Функция .getBoundingClientRect() возвращает размеры и расположение элемента в виде чисел с плавающей запятой после выполнения преобразований CSS.
> console.info(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,
}
Остерегаться! offsetHeight / offsetWidth может возвращать 0, если вы недавно внесли определенные изменения DOM в элемент. Возможно, вам придется вызвать этот код в вызове setTimeout после того, как вы изменили элемент.
При каких обстоятельствах возвращается 0?
Я не могу точно определить причину, по которой offsetWidth возвращает 0 в моем случае, потому что я изначально не писал код, но в событии onload я всегда получаю 0.
@JDandChips: offsetWidth будет 0, если элемент - display:none, тогда как вычисленный width может все еще иметь положительное значение в этом случае. visibility:hidden не влияет на offsetWidth.
clientWidth точнее?
@Supuhstar имеют разные значения. offsetWidth возвращает "весь" блок, включая содержимое, отступы и границы; в то время как clientWidth возвращает только размер окна содержимого (поэтому он будет иметь меньшее значение, когда элемент имеет ненулевое заполнение и / или границу). (мод отредактирован для наглядности)
@Supuhstar, иногда они будут такими же, например, когда вы устанавливаете box-sizing: border-box, что выполняется с помощью Bootstrap (и я уверен, что другие) автоматически.
Примечание: в случае значка внутри кнопки Chrome и firefox возвращают разные результаты: github.com/lingtalfi/browsers-behaviours/blob/master/…
Re @DanFabulich: использование requestAnimationFrame вместо setTimeout (вероятно) предпочтительнее в 2017 году.
Согласно developer.mozilla.org/en-US/docs/Web/API/HTMLElement/…, поддержка Chrome и Safari для offsetHeight неизвестна (?), И говорится, что это «экспериментальная функция» - можно ли это считать кроссбраузерностью? Этот комментарий был написан Март 2019 г.!
И смещение, и ширина клиента отображают 0, несмотря на наличие текста в div, и после щелчка мыши.
element.offsetWidth и element.offsetHeight должны работать, как было предложено в предыдущем сообщении.
Однако, если вы просто хотите центрировать контент, есть лучший способ сделать это. Предполагая, что вы используете xhtml strict DOCTYPE. установите маржу: 0, свойство auto и требуемую ширину в пикселях для тега body. Контент выравнивается по центру страницы.
Я думаю, что он тоже хочет центрировать его по вертикали, что является проблемой с CSS, если вы не можете соответствовать каким-то конкретным критериям (например, контент известного размера).
Вам нужно только рассчитать его для 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> любого размера и сжимает его до размеров своего содержимого.
также вы можете использовать этот код:
var divID = document.getElementById("divid");
var h = divID.style.pixelHeight;
Хм, работает в Chrome и IE9, похоже, не работает в Firefox. Это работает только для определенных типов документов?
pixelHeight был изобретением Internet Explorer, которое больше не должно использоваться stackoverflow.com/q/17405066/2194590
... кажется, 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>
Если offsetWidth возвращает 0, вы можете получить свойство ширины стиля элемента и выполнить поиск по нему. "100px" -> 100
/\d*/.exec(MyElement.style.width)
Взгляните на 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 в простой объект
Справка:
.offsetHeight: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight.offsetWidth: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetWidth.getBoundingClientRect(): https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRectgetboundingClientRect () вернет фактическую ширину и высоту элементов, масштабированных с помощью css, тогда как offsetHeight и offsetWidth - нет.
На всякий случай я помещаю текстовое поле, кнопку и 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
Просто чтобы прояснить ... делают ли какие-либо из этих браузеров что-нибудь иначе, чем другие? Я не могу найти никаких различий ... Кроме того, я не голосую (пока), но это не В самом деле напрямую отвечает на вопрос, хотя его можно легко отредактировать для этого.
Не был направлен на то, чтобы ответить на вопрос - на него уже был дан ответ. Просто некоторая полезная информация, и да, все основные браузеры последних версий согласны с этими значениями - и это хорошо.
Что ж ... если ваше намерение - нет, чтобы ответить на вопрос, то это на самом деле не относится к этому (как «ответ»). Я бы подумал о том, чтобы разместить это на каком-то внешнем ресурсе (возможно, в GitHub или в сообщении в блоге) и связать его в комментарии к исходному Вопросу или одному из ответов.
@ZachLysobey Из каждого правила есть исключения - и это здорово и полезно увидеть.
Согласно MDN: Определение размеров элементов
offsetWidth и offsetHeight возвращают «общий объем пространства, занимаемого элементом, включая ширину видимого содержимого, полосы прокрутки (если есть), отступы и границу».
clientWidth и clientHeight возвращают, «сколько места занимает фактически отображаемый контент, включая отступы, но не включая границу, поля или полосы прокрутки».
scrollWidth и scrollHeight возвращают «фактический размер содержимого, независимо от того, какая часть его сейчас видна».
Таким образом, это зависит от того, будет ли измеряемый контент находиться вне текущей видимой области.
спасибо: вот статья об этом javascripttutorial.net/javascript-dom/javascript-width-heigh t
Стили элементов легко изменить, но прочитать значение довольно сложно.
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.info(element);
console.info(width);
}
}
Вычисленные и разрешенные значения
В CSS есть две концепции:
A computed style value is the value after all CSS rules and CSS inheritance is applied, as the result of the CSS cascade. It can look like height:1em or font-size:125%.
A resolved style value is the one finally applied to the element. Values like 1em or 125% are relative. The browser takes the computed value and makes all units fixed and absolute, for instance: height:20px or font-size:16px. For geometry properties resolved values may have a floating point, like width:50.5px.
Давным-давно getComputedStyle был создан для получения вычисленных значений, но оказалось, что разрешенные значения намного удобнее, и стандарт изменился. Итак, в настоящее время getComputedStyle фактически возвращает разрешенное значение свойства.
Пожалуйста, обрати внимание:
getComputedStyle требует полного имени свойства
You should always ask for the exact property that you want, like paddingLeft or height or width. Otherwise the correct result is not guaranteed.
For instance, if there are properties paddingLeft/paddingTop, then what should we get for getComputedStyle(elem).padding? Nothing, or maybe a “generated” value from known paddings? There’s no standard rule here.
Есть и другие несоответствия. Например, некоторые браузеры (Chrome) показывают 10 пикселей в приведенном ниже документе, а некоторые из них (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
Вот код для 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 {
}
}
}
для ясности, это код iOS swift, верно? Не JavaScript. Я воздерживаюсь от отрицательного голоса (кстати, это может быть очень полезно), но обратите внимание, что это нет отвечает на вопрос и, вероятно, будет более подходящим для другого, специфичного для iOS, вопроса. Если его еще нет, возможно, подумайте о том, чтобы спросить его и ответить самостоятельно.
Если вы хотите отобразить на вашем <div> какое-то всплывающее сообщение в центре экрана - тогда вам не нужно читать размер <div>, но вы можете использовать сгибать
.box {
width: 50px;
height: 20px;
background: red;
}
.container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
width: 100vw;
position: fixed; /* remove this in case there is no content under div (and remember to set body margins to 0)*/
}<div class = "container">
<div class = "box">My div</div>
</div>Используйте параметр ширины следующим образом:
style = {{
width: "80%",
paddingLeft: 100,
paddingRight: 200,
paddingTop: 30,
paddingBottom: 30,
border: "3px solid lightGray",
}}
Имейте в виду, что получение высоты элемента с помощью любой метод всегда имеет значение влияние на производительность, поскольку оно заставляет браузер пересчитывать положение всех элементов на странице (перекомпоновка). Поэтому не делайте этого слишком много. Проверьте этот список, чтобы узнать, какие вещи вызывают перекомпоновку.