Как вы получаете визуализированную высоту элемента?

406

Как вы получаете визуализированную высоту элемента?

Допустим, у вас есть <div>элемент с некоторым содержанием внутри. Этот контент внутри будет растягивать высоту <div>. Как вы получаете «визуализированную» высоту, если вы явно не установили высоту. Очевидно, я попытался:

var h = document.getElementById('someDiv').style.height;

Есть ли хитрость для этого? Я использую jQuery, если это помогает.

BuddyJoe
источник
посмотреть этот ответ stackoverflow.com/questions/19581307/…
KarSho

Ответы:

183

Должно быть просто

$('#someDiv').height();

с помощью jQuery. Получает высоту первого элемента в упакованном наборе в виде числа.

Пытаясь использовать

.style.height

работает только если вы установили свойство в первую очередь. Не очень полезно!

Русь Кэм
источник
1
Одним словом - потрясающе! Спасибо всем за участие. Много хорошей информации по этой теме. Это позволит мне центрировать страницы с помощью CSS, но использовать jQuery, чтобы сделать правильной общую высоту «контейнера», не углубляясь в CSS хаквилль. Еще раз спасибо.
BuddyJoe
3
даже если вы НЕ используете jQuery или не можете или не хотите, я настоятельно рекомендую всем, кто реализует это с помощью просто offsetHeight, загружает исходный код jQuery и ищет «height», чтобы найти код, который они используют. там происходит много сумасшедших вещей!
Simon_Weaver
1
@matejkramny - этот вопрос и ответ был более 5 лет назад . Оператор уже использовал jQuery на своем сайте, так что вместо того, чтобы самому заново реализовать ту же / похожую логику, почему бы не использовать однострочную функцию jQuery, которая уже это делает? Я бы согласился, что jQuery излишне во многих отношениях, и я не боюсь vanilla JS, но когда в библиотеке есть функция, которая делает именно то, что вам нужно, кажется глупым не использовать ее, особенно по причинам «Не изобретено здесь»
Russ Cam
3
@matejkramny Цель ОП при задании вопроса состояла в том, чтобы получить визуализированную высоту элемента, а не понять, что происходит в DOM и за кулисами; если это было их намерение, они задавали неправильный вопрос. Я согласен с тем, что люди должны быть склонны понимать библиотеки и структуры, которые они используют, знание - это сила и все такое, но иногда нужно просто получить ответ на конкретный вопрос. Действительно, приведенные выше комментарии уже предлагают просмотреть код jQuery, чтобы понять, что происходит за кулисами.
Rus Cam
22
Для OP использование jQuery является правильным ответом. Для остального мира, видящего это с тех пор, ответ не-jQuery является лучшим. Возможно, ТАК нужно адаптироваться к этой реальности, возможно, ответы с наибольшим количеством голосов должны быть выделены в некотором роде больше, чем принятые.
Димитрис
1220

Попробуйте один из:

var h = document.getElementById('someDiv').clientHeight;
var h = document.getElementById('someDiv').offsetHeight;
var h = document.getElementById('someDiv').scrollHeight;

clientHeight включает в себя высоту и вертикальные отступы.

offsetHeight включает в себя высоту, вертикальные отступы и вертикальные границы.

scrollHeight включает в себя высоту содержимого документа (будет больше, чем высота в случае прокрутки), вертикальное заполнение и вертикальные границы.

strager
источник
3
Спасибо, я не знал об этой собственности. Он также совместим с IE8 +.
Любето
Я озадачен значением clientHeight. У меня есть элемент div, в котором есть куча элементов p, а содержимое выходит далеко за пределы видимой области браузера. И я ожидал, что clientHeight предоставит визуализированную высоту, а scrollHeight предоставит полную длину. Но они почти равны (отличаются только полем, отступом и т. Д.).
Бахти
10
@bahti, если только он сам не имеет ограниченной высоты и переполнения: скрытого или какой-либо формы переполнения: прокрутки, элемент развернется (независимо от того, на ваш взгляд или нет), чтобы показать весь контент, а scrollHeight и clientHeight будут равны.
Улад Касач
4
Отличный ответ, но логически границы, которые влияют на высоту элемента, - это верхняя и нижняя границы, которые являются горизонтальными. Этот ответ называет их «вертикальными границами». Просто думал, что я бы бросил свои 2 цента
Келан Крумме
1
Из того, что я знаю, .clientWidth/.clientHeight НЕ включайте ширину прокрутки, если показана прокрутка. Если вы хотите, чтобы ширина прокрутки была включена, можете использовать element.getBoundingClientRect().width вместо этого
Дмитрий Гончар
151

НЕТ JQUERY, так как elem.style.heightв верхней части этих ответов была куча ссылок ...

ВНУТРЕННЯЯ ВЫСОТА:
https://developer.mozilla.org/en-US/docs/Web/API/Element.clientHeight

document.getElementById(id_attribute_value).clientHeight;

ВЫСОКАЯ ВЫСОТА:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.offsetHeight

document.getElementById(id_attribute_value).offsetHeight; 

Или одна из моих любимых ссылок: http://youmightnotneedjquery.com/

Джейсон Лидон
источник
49

Ты можешь использовать .outerHeight() для этой цели.

Это даст вам полную визуализацию высоты элемента. Кроме того, вам не нужно устанавливать какие-либо css-heightэлементы. В качестве меры предосторожности вы можете сохранить его высоту автоматически, чтобы он мог отображаться в соответствии с высотой содержимого.

//if you need height of div excluding margin/padding/border
$('#someDiv').height();

//if you need height of div with padding but without border + margin
$('#someDiv').innerHeight();

// if you need height of div including padding and border
$('#someDiv').outerHeight();

//and at last for including border + margin + padding, can use
$('#someDiv').outerHeight(true);

Для наглядного представления этих функций вы можете перейти на сайт jQuery или подробный пост здесь .

это будет ясно разницу между .height()/ innerHeight()/outerHeight()

открытый и бесплатный
источник
1
Спасибо. При работе с поплавками у меня было много проблем с высотой авто, но тогда я был неопытен. Обычно я не устанавливал высоту, за исключением некоторого сложного сценария компоновки, в котором я первоначально очищал поле, но устанавливал его равным для каждого блока (Div), заканчивающегося одинаковой вершиной. Даже разница в один пиксель между блоками может изменить структуру при изменении размеров окон.
DHorse
1
Кстати, я думаю, что у offset есть некоторые зависимые от версии браузера варианты использования полей, которые это исключает.
DHorse
2
Вопрос не требует jQuery. Тьфу.
три
1
@dthree Я думаю, он четко упомянул, что использует jQuery. (также включенный в теги) :)
открыто и бесплатно
45

Я использую это, чтобы получить высоту элемента (возвращает float) :

document.getElementById('someDiv').getBoundingClientRect().height

Это также работает, когда вы используете виртуальный DOM . Я использую его в Vue следующим образом:

this.$refs['some-ref'].getBoundingClientRect().height
Daantje
источник
1
getBoundingClientRect (). height возвращает число с плавающей точкой (в то время как другие возвращают целое число), приятно :)
Ari
31
style = window.getComputedStyle(your_element);

тогда просто: style.height

Feiteira
источник
14

Обязательно используйте

$('#someDiv').height()   // to read it

или

$('#someDiv').height(newHeight)  // to set it

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

Я только сейчас попал в ловушку использования offsetHeight. Это то, что произошло :

  • Я использовал старый добрый прием использования отладчика, чтобы «посмотреть», какие свойства имеет мой элемент
  • Я видел, какое из них имеет значение, которое я ожидал
  • Это был offsetHeight - так что я использовал это.
  • Тогда я понял, что это не работает со скрытым DIV
  • Я пытался спрятаться после вычисления maxHeight, но это выглядело неуклюжим - попал в беспорядок.
  • Я сделал поиск - обнаружил jQuery.height () - и использовал его
  • обнаруженная высота () работает даже на скрытых элементах
  • просто для развлечения я проверил реализацию jQuery по высоте / ширине

Вот только часть этого:

Math.max(
Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
Math.max(document.body["offset" + name], document.documentElement["offset" + name])
) 

Да, это выглядит как ОБА прокрутки и смещения. Если это не удается, это выглядит еще дальше, принимая во внимание проблемы совместимости браузера и CSS. Другими словами, вещи, которые я не забочусь - или хочу.

Но я не обязан. Спасибо jQuery!

Мораль истории: если у jQuery есть метод для чего-то, то это, вероятно, по уважительной причине, вероятно, связано с совместимостью.

Если вы недавно не читали список методов jQuery, я предлагаю вам взглянуть.

Simon_Weaver
источник
Видел ваш другой комментарий на уровне вопроса. Я продан на JQuery. Был на некоторое время. Но это закрыло сделку. Я влюблен в тот факт, что эта простая вещь решит для меня сотни проблем с макетом (в основном на интранет-сайтах, где я знаю, что JavaScript работает).
BuddyJoe
13
document.querySelector('.project_list_div').offsetHeight;
Ritwik
источник
4
добавить объяснение к вашему решению
Freelancer
затем offsetHeight
Ritwik
6
Это свойство округляет значение до целого числа . Если вам нужно значение с плавающей запятой , используйтеelem.getBoundingClientRect().height
Penny Liu
12

Я сделал простой код, который даже не нуждается в JQuery и, вероятно, поможет некоторым людям. Он получает общую высоту 'ID1' после загрузки и использует его на 'ID2'

function anyName(){
    var varname=document.getElementById('ID1').offsetHeight;
    document.getElementById('ID2').style.height=varname+'px';
}

Затем просто установите тело, чтобы загрузить его

<body onload='anyName()'>
Robuske
источник
Это полезно, и я использую нечто подобное в более сложном коде.
DHorse
10

Хм, мы можем получить геометрию элемента ...

var geometry;
geometry={};
var element=document.getElementById(#ibims);
var rect = element.getBoundingClientRect();
this.geometry.top=rect.top;
this.geometry.right=rect.right;
this.geometry.bottom=rect.bottom;
this.geometry.left=rect.left;
this.geometry.height=this.geometry.bottom-this.geometry.top;
this.geometry.width=this.geometry.right-this.geometry.left;
console.log(this.geometry);

Как насчет этого простого JS?

Томас Людвиг
источник
1
var geometry; geometry={};может быть простоvar geometry={};
Марк Шультейс
10

Я думаю, что лучший способ сделать это в 2020 году - это использовать обычный JS и getBoundingClientRect().height;

Вот пример

let div = document.querySelector('div');
let divHeight = div.getBoundingClientRect().height;

console.log(`Div Height: ${divHeight}`);
<div>
  How high am I? 🥴
</div>

Помимо heightэтого, у нас также есть доступ к множеству других вещей о div.

let div = document.querySelector('div');
let divInfo = div.getBoundingClientRect();

console.log(divInfo);
<div>What else am I? 🥴</div>

Oneezy
источник
8

Так это ответ?

«Если вам нужно что-то вычислить, но не показывать, установите для элемента значение visibility:hiddenи position:absolute, добавьте его в дерево DOM, получите offsetHeight и удалите его (это то, что библиотека прототипов делает за строкой в ​​прошлый раз, когда я проверял)».

У меня та же проблема по ряду элементов. На сайте нет ни jQuery, ни прототипов, но я полностью поддерживаю заимствование техники, если она работает. В качестве примера некоторых вещей, которые не сработали, после чего я приведу следующий код:

// Layout Height Get
function fnElementHeightMaxGet(DoScroll, DoBase, elementPassed, elementHeightDefault)
{
    var DoOffset = true;
    if (!elementPassed) { return 0; }
    if (!elementPassed.style) { return 0; }
    var thisHeight = 0;
    var heightBase = parseInt(elementPassed.style.height);
    var heightOffset = parseInt(elementPassed.offsetHeight);
    var heightScroll = parseInt(elementPassed.scrollHeight);
    var heightClient = parseInt(elementPassed.clientHeight);
    var heightNode = 0;
    var heightRects = 0;
    //
    if (DoBase) {
        if (heightBase > thisHeight) { thisHeight = heightBase; }
    }
    if (DoOffset) {
        if (heightOffset > thisHeight) { thisHeight = heightOffset; }
    }
    if (DoScroll) {
        if (heightScroll > thisHeight) { thisHeight = heightScroll; }
    }
    //
    if (thisHeight == 0) { thisHeight = heightClient; }
    //
    if (thisHeight == 0) { 
        // Dom Add:
        // all else failed so use the protype approach...
        var elBodyTempContainer = document.getElementById('BodyTempContainer');
        elBodyTempContainer.appendChild(elementPassed);
        heightNode = elBodyTempContainer.childNodes[0].offsetHeight;
        elBodyTempContainer.removeChild(elementPassed);
        if (heightNode > thisHeight) { thisHeight = heightNode; }
        //
        // Bounding Rect:
        // Or this approach...
        var clientRects = elementPassed.getClientRects();
        heightRects = clientRects.height;
        if (heightRects > thisHeight) { thisHeight = heightRects; }
    }
    //
    // Default height not appropriate here
    // if (thisHeight == 0) { thisHeight = elementHeightDefault; }
    if (thisHeight > 3000) {
        // ERROR
        thisHeight = 3000;
    }
    return thisHeight;
}

который в основном пытается что-нибудь и все, только чтобы получить нулевой результат. ClientHeight без каких-либо последствий. С проблемными элементами я обычно получаю NaN в базе и ноль в высотах смещения и прокрутки. Затем я попытался добавить решение DOM и clientRects, чтобы увидеть, работает ли оно здесь.

29 июня 2011 года я действительно обновил код, чтобы попытаться добавить DOM и clientHeight с лучшими результатами, чем я ожидал.

1) clientHeight также был 0.

2) Дом на самом деле дал мне рост, который был отличным.

3) ClientRects возвращает результат, почти идентичный методу DOM.

Поскольку добавленные элементы являются текучими по своей природе, при добавлении их в пустой элемент Temp DOM в противном случае они отображаются в соответствии с шириной этого контейнера. Это странно, потому что это на 30px короче, чем в итоге получается.

Я добавил несколько снимков, чтобы проиллюстрировать, как высота рассчитывается по-разному. Блок меню отображается нормально Блок меню добавлен в элемент DOM Temp

Разница в высоте очевидна. Я, конечно, мог бы добавить абсолютное позиционирование и скрытое, но я уверен, что это не будет иметь никакого эффекта. Я продолжал убеждаться, что это не сработает!

(Я отвлекаюсь дальше) Высота получается (отображается) ниже, чем истинная отображаемая высота. Эту проблему можно решить, установив ширину элемента DOM Temp в соответствии с существующим родителем, и теоретически это можно сделать довольно точно. Я также не знаю, что произойдет, если удалить их и добавить обратно в их существующее местоположение. Когда они пришли через метод innerHTML, я буду искать, используя этот другой подход.

* ОДНАКО * Ничего из этого не было необходимо. Фактически это работало как рекламируется и возвратило правильную высоту !!!

Когда я смог снова увидеть меню, DOM вернул правильную высоту в соответствии с макетом жидкости в верхней части страницы (279 пикселей). Приведенный выше код также использует getClientRects, которые возвращают 280px.

Это показано на следующем снимке (взятом из Chrome после работы.)
введите описание изображения здесь

Теперь у меня нет идеи, почему этот трюк с прототипом работает, но, похоже, это так. Кроме того, getClientRects также работает.

Я подозреваю, что причиной всех этих проблем с этими конкретными элементами было использование innerHTML вместо appendChild, но на данный момент это чистое предположение.

DHorse
источник
6

offsetHeight, как правило.

Если вам нужно что-то вычислить, но не показать, установите для элемента значение visibility:hiddenи position:absolute, добавьте его в дерево DOM, получите offsetHeightи удалите его. (Это то, что библиотека прототипов делает за кулисами в прошлый раз, когда я проверял).

htoip
источник
интересно. Я никогда не проверял прототип. Есть идеи, почему jQuery не делает этого за кадром?
Simon_Weaver
Я видел это, когда испытывал трудности, и проверял эту технику, и она довольно хорошо работала на простом JavaScript
DHorse
5

Иногда offsetHeight будет возвращать ноль, потому что созданный вами элемент еще не отрисован в Dom. Я написал эту функцию для таких обстоятельств:

function getHeight(element)
{
    var e = element.cloneNode(true);
    e.style.visibility = "hidden";
    document.body.appendChild(e);
    var height = e.offsetHeight + 0;
    document.body.removeChild(e);
    e.style.visibility = "visible";
    return height;
}
Лонни Бест
источник
вам нужно клонировать элемент, иначе он будет полностью удален из dom, кажется, из вашего кода вот что произойдет.
панкбит
Этот код не предназначен для хранения элемента в DOM. Он предназначен для того, чтобы поместить его в DOM ненадолго (достаточно долго, чтобы отрендерить и получить его высоту), а затем вынуть его. Позже вы можете поместить элемент в дом позже (зная, какой будет его высота, прежде чем вы это сделаете). Обратите внимание на имя функции «getHeight»; это все, что намеревается сделать код.
Лонни Бест
@punkbit: Я понимаю, что ты имеешь в виду. Твоя стихия уже в домике. Код, который я написал, предназначен для элемента, которого еще нет в DOM. Как вы говорите, клонирование будет лучше, потому что не имеет значения, находится элемент в домике или нет.
Лонни Бест
@punkbit: я модифицировал код, используя клонирование, но не проверял его.
Лонни Бест
да, это была моя точка зрения. Мне показалось, что он говорит «элемент» для существующего элемента в DOM. Но все хорошо! Не поймите это неправильно.
панкбит
4

Если вы уже используете jQuery, лучше всего выбрать .outerHeight()или .height(), как уже было сказано.

Без jQuery вы можете проверить размер используемого блока и добавить различные отступы + border + clientHeight, или вы можете использовать getComputedStyle :

var h = getComputedStyle (document.getElementById ('someDiv')). height;

h теперь будет выглядеть как "53.825px".

И я не могу найти ссылку, но я думаю, что слышал, что это getComputedStyle()может быть дорого, поэтому, вероятно, это не то, что вы хотите вызывать в каждом window.onscrollсобытии (но, в то же время, это не jQuery height()).

chbrown
источник
Как только у вас будет высота от getComputedStyle, используйте, parseInt(h, 10)чтобы получить целое число для расчетов.
RhodanV5500
1

Если я правильно понял ваш вопрос, то, возможно, что-то подобное поможет:

function testDistance(node1, node2) {
    /* get top position of node 1 */
    let n1Pos = node1.offsetTop;
    /* get height of node 1 */
    let n1Height = node1.clientHeight;
    /* get top position of node 2 */
    let n2Pos = node2.offsetTop;
    /* get height of node 2 */
    let n2Height = node2.clientHeight;

    /* add height of both nodes */
    let heightTogether = n1Height + n2Height;
    /* calculate distance from top of node 1 to bottom of node 2 */
    let actualDistance = (n2Pos + n2Height) - n1Pos;

    /* if the distance between top of node 1 and bottom of node 2
       is bigger than their heights combined, than there is something between them */
    if (actualDistance > heightTogether) {
        /* do something here if they are not together */
        console.log('they are not together');
    } else {
        /* do something here if they are together */
        console.log('together');
    } 
}
LuisBento
источник
-4

Вы специально установили высоту в CSS? Если у вас нет, вам нужно использовать, offsetHeight;а неheight

var h = document.getElementById('someDiv').style.offsetHeight;
Стирпайк
источник
8
offsetHeight - это свойство самого элемента, а не его стиля.
Shog9