Como você obtém a altura renderizada de um elemento?

406

Como você obtém a altura renderizada de um elemento?

Digamos que você tenha um <div>elemento com algum conteúdo interno. Este conteúdo interno vai esticar a altura do <div>. Como você obtém a altura "renderizada" quando você não definiu explicitamente a altura. Obviamente, eu tentei:

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

Existe um truque para fazer isso? Eu estou usando jQuery, se isso ajuda.

BuddyJoe
fonte
veja esta resposta stackoverflow.com/questions/19581307/…
KarSho 25/10

Respostas:

183

Deveria ser apenas

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

com jQuery. Isso recupera a altura do primeiro item no conjunto agrupado como um número.

Tentando usar

.style.height

só funciona se você tiver definido a propriedade em primeiro lugar. Não é muito útil!

Russ Cam
fonte
11
Uma palavra - incrível! Obrigado pela participação de todos. Muitas informações boas sobre este tópico. Isso permitirá que eu centralize as páginas usando CSS, mas use o jQuery para corrigir a altura geral da div "container" sem se aventurar no CSS hackville. Obrigado novamente.
9609 BuddyJoe
3
mesmo se você NÃO estiver usando jQuery ou não puder ou não quiser, sugiro fortemente que alguém implemente isso usando apenas offsetHeight prossegue e baixa a fonte do jQuery e pesquisa "height" para encontrar o código que eles usam. muita coisa louca acontecendo lá!
22416 Simon_Weaver
11
@matejkramny - Esta pergunta e resposta foram mais de 5 anos atrás . O OP já estava usando o jQuery no site deles, em vez de reimplementar a mesma lógica / similar, por que não usar a função jQuery de uma linha que já faz isso? Concordo que o jQuery é um exagero para muitas coisas e não tenho medo do JS baunilha, mas quando há uma função em uma biblioteca que faz exatamente o que você precisa, parece bobagem não usá-lo, principalmente por razões de "Não inventado aqui"
Russ Cam
3
@matejkramny A intenção dos OPs ao fazer a pergunta era obter a altura renderizada do elemento, não entender o que está acontecendo no DOM e nos bastidores; se essa era a intenção deles, eles fizeram a pergunta errada. Concordo que as pessoas devem estar inclinadas a entender as bibliotecas e estruturas que usam, o conhecimento é poder e tudo mais, mas às vezes alguém só quer uma resposta para uma pergunta específica. De fato, os comentários acima já sugerem olhar o código do jQuery para entender o que está acontecendo nos bastidores.
Russ Cam
22
Para o OP, o uso do jQuery é uma resposta válida. Para o resto do mundo vendo isso a partir de então, a resposta não-jQuery é a melhor. Talvez o SO precise se adaptar a essa realidade, talvez as respostas mais votadas devam ser destacadas de alguma forma mais do que as aceitas.
Dimitris
1220

Experimente um dos seguintes:

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

clientHeight inclui a altura e o preenchimento vertical.

offsetHeight inclui altura, preenchimento vertical e bordas verticais.

scrollHeight inclui a altura do documento contido (seria maior do que apenas a altura no caso de rolagem), preenchimento vertical e bordas verticais.

strager
fonte
3
Obrigado, eu não sabia sobre essa propriedade. Também é compatível com o IE8 +.
lyubeto
Estou perplexo com o significado de clientHeight. Eu tenho um elemento div que possui vários elementos p e o conteúdo vai muito além da área visível do navegador para baixo. E eu esperava que clientHeight fornecesse a altura renderizada e scrollHeight fornecesse o comprimento total. Mas eles são quase iguais (diferindo apenas por margem, preenchimento etc.).
Bahti
10
@bahti, a menos que ele tenha uma altura limitada e um estouro: oculto ou alguma forma de estouro: scroll, o elemento será expandido (na sua opinião ou não) para mostrar todo o conteúdo e scrollHeight e clientHeight serão iguais.
Ulad Kasach
4
Ótima resposta, mas logicamente, as bordas que afetam a altura de um elemento são as bordas superior e inferior, que são horizontais. Esta resposta se refere a eles como "bordas verticais". Apenas pensei em cair meus 2 centavos #
Kehlan Krumme 13/10
11
Pelo que sei, .clientWidth/.clientHeight NÃO inclua a largura da rolagem se a rolagem for mostrada. Se você quiser largura de rolagem para ser incluído, pode usar element.getBoundingClientRect().width em vez
Dmitry Gonchar
49

Você pode usar .outerHeight()para esse fim.

Ele fornecerá a altura renderizada completa do elemento. Além disso, você não precisa definir nenhum css-heightelemento. Por precaução, você pode manter sua altura automaticamente para que possa ser renderizada conforme a altura do conteúdo.

//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);

Para uma visão clara dessas funções, você pode acessar o site do jQuery ou uma publicação detalhada aqui .

limpará a diferença entre .height()/ innerHeight()/outerHeight()

aberto e livre
fonte
11
Obrigado. Ao trabalhar com carros alegóricos, tive muitos problemas com a altura automática, mas era inexperiente na época. Geralmente, não defini a altura, exceto em algum script de layout complexo, onde limpei o campo inicialmente, mas o defini como igual para cada bloco (Div) que termina com o mesmo topo. Mesmo uma diferença de um pixel entre os blocos pode danificar o layout ao redimensionar janelas.
DHorse
11
BTW, acho que o offset tem alguns usos dependentes da versão do navegador em relação às margens que isso elimina.
DHorse
2
A questão não exige jQuery. Ugh.
dthree 31/07
11
@dthree Eu acho que ele claramente mencionado que ele está usando jQuery (também incluído no Tag) :).
aberto e gratuito
45

Eu uso isso para obter a altura de um elemento (retorna float) :

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

Também funciona quando você usa o DOM virtual . Eu uso no Vue assim:

this.$refs['some-ref'].getBoundingClientRect().height
Daantje
fonte
11
getBoundingClientRect () altura retorna um número de ponto flutuante (enquanto os outros retornam inteiro), agradável :).
Ari
31
style = window.getComputedStyle(your_element);

então simplesmente: style.height

Feiteira
fonte
14

Definitivamente usar

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

ou

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

Estou postando isso como uma resposta adicional, porque há algumas coisas importantes que acabei de aprender.

Eu quase caí na armadilha agora de usar offsetHeight. Isso é o que aconteceu :

  • Usei o bom e velho truque de usar um depurador para 'observar' quais propriedades meu elemento possui
  • Eu vi qual deles tem um valor em torno do valor que eu esperava
  • Foi offsetHeight - então eu usei isso.
  • Então eu percebi que não funcionava com um DIV oculto
  • Tentei me esconder depois de calcular o maxHeight, mas isso parecia desajeitado - ficou uma bagunça.
  • Eu fiz uma pesquisa - descobri o jQuery.height () - e usei
  • descobri que height () funciona mesmo em elementos ocultos
  • só por diversão, verifiquei a implementação do jQuery de altura / largura

Aqui está apenas uma parte:

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

Sim, ele olha para ambos rolagem e deslocamento. Se isso falhar, parece ainda mais, levando em consideração os problemas de compatibilidade do navegador e do css. Em outras palavras, MATERIAL NÃO ME IMPORTO - ou quero.

Mas eu não preciso. Obrigado jQuery!

Moral da história: se o jQuery tem um método para algo, provavelmente por um bom motivo, provavelmente relacionado à compatibilidade.

Se você não leu a lista de métodos do jQuery recentemente, sugiro que você dê uma olhada.

Simon_Weaver
fonte
Viu seu outro comentário no nível da pergunta. Eu sou vendido no jQuery. Já faz um tempo. Mas isso selou o acordo. Estou apaixonada pelo fato de que essa coisa simples vai resolver centenas de problemas de layout para mim (principalmente em sites da Intranet onde sei que o JavaScript está sendo executado).
22410 BuddyJoe
13
document.querySelector('.project_list_div').offsetHeight;
Ritwik
fonte
4
adicione explicação à sua solução
Freelancer
então offsetHeight
Ritwik
6
Esta propriedade arredondará o valor para um número inteiro . Se você precisa de um flutuador valor, useelem.getBoundingClientRect().height
Penny Liu
12

Eu criei um código simples que nem precisa do JQuery e provavelmente vai ajudar algumas pessoas. Ele obtém a altura total de 'ID1' depois de carregado e usa-o em 'ID2'

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

Em seguida, basta definir o corpo para carregá-lo

<body onload='anyName()'>
Robuske
fonte
É útil e emprego algo semelhante em código mais complexo.
DHorse
10

Hm, podemos obter a geometria do elemento ...

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);

E esse JS simples?

Thomas Ludewig
fonte
11
var geometry; geometry={};pode simplesmente servar geometry={};
Mark Schultheiss 02/01
10

Eu acho que a melhor maneira de fazer isso em 2020 é usar js simples e getBoundingClientRect().height;

Aqui está um exemplo

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

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

Além heightdisso, também temos acesso a várias outras coisas sobre o div.

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

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

Oneezy
fonte
8

Então esta é a resposta?

"Se você precisar calcular algo, mas não mostrar, defina o elemento como visibility:hiddene position:absoluteadicione-o à árvore DOM, obtenha o offsetHeight e remova-o. (É o que a biblioteca de protótipos faz atrás das linhas da última vez que verifiquei)."

Eu tenho o mesmo problema em vários elementos. Não há jQuery ou Prototype para ser usado no site, mas sou a favor de pedir emprestada a técnica, se funcionar. Como exemplo de algumas coisas que não funcionaram, seguidas pelo que aconteceu, tenho o seguinte código:

// 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;
}

que basicamente tenta de tudo para obter um resultado zero. ClientHeight sem efeito. Com os elementos problemáticos, normalmente recebo NaN na Base e zero nas alturas Offset e Scroll. Tentei a solução Add DOM e o clientRects para ver se funciona aqui.

Em 29 de junho de 2011, atualizei o código para tentar adicionar ao DOM e ao clientHeight com melhores resultados do que eu esperava.

1) clientHeight também foi 0.

2) Dom realmente me deu uma altura que foi ótima.

3) ClientRects retorna um resultado quase idêntico à técnica DOM.

Como os elementos adicionados são fluidos por natureza, quando são adicionados a um elemento DOM Temp vazio, eles são renderizados de acordo com a largura desse contêiner. Isso fica estranho, porque é 30px mais curto do que acaba.

Adicionei alguns instantâneos para ilustrar como a altura é calculada de maneira diferente. Bloco de menu processado normalmente Bloco de menu adicionado ao elemento DOM Temp

As diferenças de altura são óbvias. Eu certamente poderia adicionar posicionamento absoluto e oculto, mas tenho certeza de que isso não terá efeito. Continuei convencido de que isso não funcionaria!

(Discordo mais) A altura sai (é renderizada) menor que a verdadeira altura renderizada. Isso poderia ser resolvido configurando a largura do elemento DOM Temp para corresponder ao pai existente e poderia ser feito com bastante precisão na teoria. Também não sei o que resultaria de removê-los e adicioná-los novamente ao local existente. Como eles chegaram através de uma técnica innerHTML, estarei procurando usar essa abordagem diferente.

* NO ENTANTO * Nada disso foi necessário. Na verdade, funcionou como anunciado e retornou a altura correta !!!

Quando consegui tornar os menus visíveis novamente, o DOM retornou a altura correta de acordo com o layout do fluido na parte superior da página (279px). O código acima também usa getClientRects que retornam 280px.

Isso é ilustrado no instantâneo a seguir (tirado do Chrome depois de funcionar).
insira a descrição da imagem aqui

Agora não tenho idéia do por que esse truque de protótipo funciona, mas parece que sim. Como alternativa, getClientRects também funciona.

Suspeito que a causa de todo esse problema com esses elementos em particular tenha sido o uso do innerHTML em vez do appendChild, mas isso é pura especulação neste momento.

DHorse
fonte
6

offsetHeight, usualmente.

Se você precisar calcular algo, mas não mostrar, defina o elemento como visibility:hiddene position:absolute, adicione-o à árvore DOM, obtenha o offsetHeighte remova-o. (Isso é o que a biblioteca de protótipos faz nos bastidores da última vez que verifiquei).

htoip
fonte
interessante. Eu nunca verifiquei o protótipo. Alguma idéia de por que o jQuery não faz isso nos bastidores?
23410 Simon_Weaver
Vi que quando a ter dificuldades e testado que técnica e funcionou muito bem em JavaScript simples
DHorse
5

Às vezes, offsetHeight retornará zero porque o elemento que você criou ainda não foi renderizado no Dom. Eu escrevi esta função para tais circunstâncias:

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;
}
Lonnie Best
fonte
você precisa clonar o elemento, caso contrário ele será removido do domínio completamente, parece que seu código é o que acontecerá.
punkbit
Este código não se destina a manter o elemento no DOM. Destina-se a colocá-lo no DOM apenas brevemente (tempo suficiente para renderizá-lo e obter sua altura) e, em seguida, retirá-lo. Posteriormente, você pode colocar o elemento no dom em outro lugar (sabendo qual será sua altura antes de você). Observe o nome da função "getHeight"; isso é tudo o que o código pretende fazer.
Lonnie Melhor
@punkbit: Entendo o que você quer dizer. Seu elemento já está no domínio. O código que escrevi é para um elemento que ainda não está no DOM. A clonagem seria melhor, como você diz, porque não importa se o elemento está no domínio ou não.
Lonnie Melhor
@ punkbit: eu modifiquei o código de clonagem, mas não o testei.
Lonnie Melhor
Sim, esse foi o meu ponto. Pareceu-me que ele diz "elemento" para um elemento existente no DOM. Mas tudo de bom! Não me entenda mal.
punkbit
4

Se você já usa o jQuery, sua melhor aposta é .outerHeight()ou .height(), como já foi afirmado.

Sem o jQuery, você pode verificar o tamanho da caixa em uso e adicionar vários preenchimentos + bordas + clientHeight, ou pode usar getComputedStyle :

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

h agora será uma sequência como "53.825px".

E não consigo encontrar a referência, mas acho que ouvi getComputedStyle()pode ser caro, então provavelmente não é algo que você queira chamar em cada window.onscrollevento (mas também não é o jQuery height()).

chbrown
fonte
Depois de ter a altura de getComputedStyle, use parseInt(h, 10)para obter um número inteiro para cálculos.
RodanV5500
2

Com o MooTools :

$('someDiv').getSize().y

kwcto
fonte
1

Se entendi sua pergunta corretamente, talvez algo assim ajude:

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
fonte
-4

Você definiu a altura no css especificamente? Se você não tiver, precisa usar em offsetHeight;vez deheight

var h = document.getElementById('someDiv').style.offsetHeight;
Steerpike
fonte
8
offsetHeight é uma propriedade do próprio elemento, não do seu estilo.
8119 Shog9