Come si ottiene l'altezza di rendering di un elemento?


406

Come si ottiene l'altezza di rendering di un elemento?

Supponiamo che tu abbia un <div>elemento con alcuni contenuti all'interno. Questo contenuto al suo interno allungherà l'altezza di <div>. Come si ottiene l'altezza "renderizzata" quando non è stata impostata l'altezza in modo esplicito. Ovviamente, ho provato:

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

C'è un trucco per farlo? Sto usando jQuery se questo aiuta.


Risposte:


183

Dovrebbe essere

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

con jQuery. In questo modo viene recuperata l'altezza del primo elemento nell'insieme spostato come numero.

Cercando di usare

.style.height

funziona solo se hai impostato la proprietà in primo luogo. Non molto utile!


1
Una parola: fantastico! Grazie per la partecipazione di tutti. Molte buone informazioni su questa discussione. Questo mi permetterà di centrare le pagine usando i CSS ma usare jQuery per rendere corretta l'altezza complessiva del div "container" senza avventurarmi in hackville CSS. Grazie ancora.
BuddyJoe,

3
anche se NON stai usando jQuery o non puoi o non voglio suggerire vivamente a nessuno di implementarlo usando solo offsetHeight va avanti e scarica la fonte jQuery e cerca "height" per trovare il codice che usano. ci sono un sacco di cose folli che succedono lì!
Simon_Weaver,

1
@matejkramny - Questa domanda e risposta era oltre 5 anni fa . L'OP stava già utilizzando jQuery sul proprio sito, quindi piuttosto che implementare nuovamente la stessa / simile logica, perché non utilizzare la funzione jQuery su una riga che già lo fa? Concordo sul fatto che jQuery sia eccessivo per molte cose e non ho paura della vaniglia JS, ma quando c'è una funzione in una libreria che fa esattamente ciò di cui hai bisogno, sembra sciocco non usarla, in particolare per motivi di "Non inventato qui"
Russ Cam

3
@matejkramny L'intenzione dei PO quando si poneva la domanda era di ottenere l'altezza di rendering dell'elemento, non di capire cosa stava succedendo nel DOM e dietro le quinte; se questa era la loro intenzione, hanno posto la domanda sbagliata. Concordo sul fatto che le persone dovrebbero essere inclini a comprendere le biblioteche e le strutture che usano, la conoscenza è potere e tutto il resto, ma a volte si vuole solo una risposta a una domanda specifica. In effetti, i commenti sopra suggeriscono già di guardare attraverso il codice jQuery per capire cosa sta succedendo dietro le quinte.
Russ Cam

22
Per l'OP, l'utilizzo di jQuery è una risposta valida. Per il resto del mondo, visto questo da allora in poi, la risposta non jQuery è la migliore. Forse SO deve adattarsi a quella realtà, forse le risposte più votate dovrebbero essere evidenziate in qualche modo più di quelle accettate.
Dimitris,

1220

Prova uno di:

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

clientHeight include l'altezza e l'imbottitura verticale.

offsetHeight include l'altezza, l'imbottitura verticale e i bordi verticali.

scrollHeight include l'altezza del documento contenuto (sarebbe maggiore della sola altezza in caso di scorrimento), imbottitura verticale e bordi verticali.


3
Grazie, non sapevo di questa proprietà. È compatibile anche con IE8 +.
Lyubeto,

Sono perplesso con il significato di clientHeight. Ho un elemento div che contiene un sacco di elementi p e il contenuto va ben oltre l'area visualizzabile del browser verso il basso. E mi aspettavo che clientHeight fornisse l'altezza di rendering e scrollHeight per fornire l'intera lunghezza. Ma sono quasi uguali (differiscono solo per margine, imbottitura ecc.).
bahti,

10
@bahti a meno che non abbia un'altezza limitata e un overflow: nascosto o una qualche forma di overflow: scroll, l'elemento si espanderà (a tuo avviso o meno) per mostrare tutto il contenuto e scrollHeight e clientHeight saranno uguali.
Ulad Kasach,

4
Ottima risposta, ma logicamente, i bordi che influenzano l'altezza di un elemento sono i bordi superiore e inferiore, che sono orizzontali. Questa risposta si riferisce a loro come "bordi verticali". Ho pensato di perdere i miei 2 centesimi
Kehlan Krumme,

1
Da quello che so, .clientWidth/.clientHeight NON includere la larghezza di scorrimento se viene mostrato lo scorrimento. Se si desidera includere la larghezza di scorrimento, è possibile utilizzare element.getBoundingClientRect().width invece
Dmitry Gonchar,

151

NON JQUERY poiché elem.style.heightnella parte superiore di queste risposte c'erano un sacco di collegamenti che utilizzavano ...

ALTEZZA INTERNA:
https://developer.mozilla.org/en-US/docs/Web/API/Element.clientHeight

document.getElementById(id_attribute_value).clientHeight;

ALTEZZA ESTERNA:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.offsetHeight

document.getElementById(id_attribute_value).offsetHeight; 

O uno dei miei riferimenti preferiti: http://youmightnotneedjquery.com/


49

È possibile utilizzare .outerHeight()per questo scopo.

Ti darà l'altezza di rendering dell'elemento. Inoltre, non è necessario impostare alcun css-heightelemento. Per precauzione è possibile mantenere la sua altezza automatica in modo che possa essere renderizzato secondo l'altezza del contenuto.

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

Per una visione chiara di queste funzioni puoi visitare il sito di jQuery o un post dettagliato qui .

cancellerà la differenza tra .height()/ innerHeight()/outerHeight()


1
Grazie. Nel lavorare con i galleggianti ho avuto molti problemi con l'altezza automatica, ma allora non avevo esperienza. In genere non ho impostato l'altezza, tranne in alcuni script di layout complessi in cui inizialmente deseleziono il campo ma lo imposto in modo che sia uguale per ogni blocco (Div) che termina con la stessa parte superiore. Anche una differenza di un pixel tra i blocchi può rovinare il layout quando si ridimensionano le finestre.
DHorse,

1
A proposito, penso che offset abbia alcuni usi dipendenti dalla versione del browser per quanto riguarda i margini che questo elimina.
DHorse,

2
La domanda non richiede jQuery. Ugh.
tre

1
@dthree Penso che abbia menzionato chiaramente che sta usando jQuery. (incluso anche nei tag) :)
aperto e gratuito il

45

Lo uso per ottenere l'altezza di un elemento (restituisce float) :

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

Funziona anche quando si utilizza il DOM virtuale . Lo uso in Vue in questo modo:

this.$refs['some-ref'].getBoundingClientRect().height

1
getBoundingClientRect (). height restituisce un numero in virgola mobile (mentre gli altri restituiscono un numero intero), bello :)
Ari

31
style = window.getComputedStyle(your_element);

quindi semplicemente: style.height


14

Sicuramente usare

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

o

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

Sto postando questo come risposta aggiuntiva perché ci sono un paio di cose importanti che ho appena imparato.

Sono quasi caduto nella trappola proprio ora di usare offsetHeight. Questo è quello che è successo :

  • Ho usato il buon vecchio trucco di usare un debugger per 'guardare' quali proprietà ha il mio elemento
  • Ho visto quale ha un valore attorno al valore che mi aspettavo
  • Era offsetHeight, quindi l'ho usato.
  • Poi ho capito che non funzionava con un DIV nascosto
  • Ho provato a nascondermi dopo aver calcolato maxHeight ma sembrava goffo - ho avuto un casino.
  • Ho fatto una ricerca - ho scoperto jQuery.height () - e l'ho usato
  • scoperto altezza () funziona anche su elementi nascosti
  • solo per divertimento ho controllato l'implementazione jQuery di altezza / larghezza

Eccone solo una parte:

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

Sì, guarda ENTRAMBI lo scorrimento e l'offset. Se fallisce, guarda ancora oltre, tenendo conto dei problemi di compatibilità con browser e CSS. In altre parole, STUFF, NON HO CURA DI - o voglio farlo.

Ma non devo. Grazie jQuery!

Morale della storia: se jQuery ha un metodo per qualcosa, probabilmente è per una buona ragione, probabilmente correlata alla compatibilità.

Se non hai letto di recente l' elenco dei metodi jQuery, ti suggerisco di dare un'occhiata.


Ho visto l'altro tuo commento a livello di domanda. Sono venduto su jQuery. Sono stato per un po '. Ma questo ha sigillato l'affare. Sono innamorato del fatto che questa semplice cosa risolverà per me centinaia di problemi di layout (principalmente su siti Intranet in cui so che JavaScript è in esecuzione).
BuddyJoe,

13
document.querySelector('.project_list_div').offsetHeight;

4
aggiungi spiegazione alla tua soluzione
Freelancer

quindi offsetHeight
Ritwik

6
Questa proprietà arrotonderà il valore a un numero intero . Se hai bisogno di un valore float , usaelem.getBoundingClientRect().height
Penny Liu il

12

Ho creato un codice semplice che non ha nemmeno bisogno di JQuery e probabilmente aiuterà alcune persone. Ottiene l'altezza totale di 'ID1' dopo il caricamento e la usa su 'ID2'

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

Quindi imposta il corpo per caricarlo

<body onload='anyName()'>

È utile e utilizzo qualcosa di simile in un codice più complesso.
DHorse,

10

Possiamo ottenere la geometria dell'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);

Che ne dici di questo semplice JS?


1
var geometry; geometry={};può semplicemente esserevar geometry={};
Mark Schultheiss il

10

Penso che il modo migliore per farlo nel 2020 sia usare js e getBoundingClientRect().height;

Ecco un esempio

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

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

Oltre a ottenere in heightquesto modo, abbiamo anche accesso a un sacco di altre cose su div.

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

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


8

Quindi questa è la risposta?

"Se devi calcolare qualcosa ma non mostrarlo, imposta l'elemento su visibility:hiddene position:absolute, aggiungilo all'albero DOM, ottieni offsetHeight e rimuovilo. (Ecco cosa fa la libreria dei prototipi dietro le righe l'ultima volta che ho controllato)."

Ho lo stesso problema su un numero di elementi. Non c'è jQuery o Prototype da utilizzare sul sito, ma sono tutti a favore di prendere in prestito la tecnica se funziona. Come esempio di alcune cose che non hanno funzionato, seguito da quello che ho fatto, ho il seguente codice:

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

che fondamentalmente cerca di tutto e di tutto solo per ottenere un risultato zero. ClientHeight senza alcun effetto. Con gli elementi problematici ottengo normalmente NaN nella Base e zero nelle altezze di Scostamento e Scorrimento. Ho quindi provato la soluzione Aggiungi DOM e clientRects per vedere se funziona qui.

29 giu 2011, ho effettivamente aggiornato il codice per provare sia ad aggiungere a DOM che a clientHeight con risultati migliori di quanto mi aspettassi.

1) clientHeight era anche 0.

2) Dom in realtà mi ha dato un'altezza che è stata grandiosa.

3) ClientRects restituisce un risultato quasi identico alla tecnica DOM.

Poiché gli elementi aggiunti sono di natura fluida, quando vengono aggiunti a un elemento DOM DOM altrimenti vuoto vengono renderizzati in base alla larghezza di quel contenitore. Questo diventa strano, perché è 30px più corto di quello che alla fine finisce.

Ho aggiunto alcune istantanee per illustrare come l'altezza viene calcolata in modo diverso. Blocco menu reso normalmente Blocco menu aggiunto all'elemento DOM Temp

Le differenze di altezza sono evidenti. Potrei sicuramente aggiungere un posizionamento assoluto e nascosto, ma sono sicuro che non avrà alcun effetto. Ho continuato a essere convinto che non avrebbe funzionato!

(Sto divagando ulteriormente) L'altezza viene fuori (rendering) inferiore alla vera altezza di rendering. Questo potrebbe essere risolto impostando la larghezza dell'elemento DOM DOM in modo che corrisponda al genitore esistente e potrebbe essere fatto in modo abbastanza accurato in teoria. Inoltre, non so cosa sarebbe il risultato della loro rimozione e dell'aggiunta di nuovo nella loro posizione esistente. Come sono arrivati ​​attraverso una tecnica innerHTML, cercherò di utilizzare questo approccio diverso.

* TUTTAVIA * Niente di tutto ciò era necessario. In effetti ha funzionato come pubblicizzato e ha restituito l'altezza corretta !!!

Quando sono stato in grado di rendere nuovamente visibili i menu, DOM ha restituito l'altezza corretta per il layout fluido nella parte superiore della pagina (279 px). Il codice sopra usa anche getClientRects che restituisce 280px.

Questo è illustrato nella seguente istantanea (presa da Chrome una volta che funziona).
inserisci qui la descrizione dell'immagine

Ora non ho idea del perché quel trucco prototipo funzioni, ma sembra. In alternativa, anche getClientRects funziona.

Sospetto che la causa di tutti questi problemi con questi elementi particolari sia stata l'uso di innerHTML invece di appendChild, ma a questo punto è pura speculazione.


6

offsetHeight, generalmente.

Se è necessario calcolare qualcosa ma non mostrarlo, impostare l'elemento su visibility:hiddene position:absolute, aggiungerlo all'albero DOM, ottenere il offsetHeighte rimuoverlo. (Questo è ciò che la libreria prototipi fa dietro le quinte l'ultima volta che ho controllato).


interessante. non ho mai controllato il prototipo. qualche idea sul perché jQuery non lo faccia dietro le quinte?
Simon_Weaver,

Ho visto che quando ho avuto difficoltà e ho provato quella tecnica e ha funzionato abbastanza bene in JavaScript
DHorse,

5

A volte offsetHeight restituisce zero perché l'elemento che hai creato non è stato ancora reso nel Dom. Ho scritto questa funzione per tali circostanze:

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

devi clonare l'elemento, altrimenti verrà rimosso completamente dalla dom sembra dal tuo codice che è quello che succederà.
punkbit,

Questo codice non ha lo scopo di mantenere l'elemento nel DOM. È destinato a inserirlo nel DOM solo brevemente (abbastanza a lungo per renderlo e ottenere la sua altezza), quindi lo elimina. Successivamente puoi inserire l'elemento nel dom altrove in seguito (sapendo quale sarà la sua altezza prima di farlo). Notare il nome della funzione "getHeight"; questo è tutto ciò che il codice intende fare.
Lonnie Best

@punkbit: capisco cosa intendi. Il tuo elemento è già nel dom. Il codice che ho scritto è per un elemento che non è ancora nel DOM. La clonazione sarebbe meglio, come dici tu, perché non importa se l'elemento è nel dom o no.
Lonnie Best

@punkbit: ho modificato il codice usando la clonazione, ma non l'ho provato.
Lonnie Best

sì, quello era il mio punto. Mi è sembrato che dicesse "elemento" per un elemento esistente nel DOM. Ma tutto bene! Non sbagliare.
punkbit

4

Se stai già utilizzando jQuery, la tua scommessa migliore è .outerHeight()o .height(), come è stato affermato.

Senza jQuery, puoi controllare il dimensionamento delle caselle in uso e aggiungere vari padding + bordi + clientHeight oppure puoi utilizzare getComputedStyle :

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

h sarà ora una stringa come "53.825px".

E non riesco a trovare il riferimento, ma penso di aver sentito che getComputedStyle()può essere costoso, quindi probabilmente non è qualcosa che vuoi chiamare per ogni window.onscrollevento (ma poi, non lo è nemmeno per jQuery height()).


Una volta che hai l'altezza da getComputedStyle, usa parseInt(h, 10)per ottenere un numero intero per i calcoli.
RhodanV5500,


1

Se avessi capito correttamente la tua domanda, forse qualcosa del genere sarebbe di aiuto:

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

-4

Hai impostato l'altezza nello specifico CSS? In caso contrario, è necessario utilizzare offsetHeight;anzichéheight

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

8
offsetHeight è una proprietà dell'elemento stesso, non del suo stile.
Shog9,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.