Jak uzyskać renderowaną wysokość elementu?

405

Jak uzyskać renderowaną wysokość elementu?

Załóżmy, że masz <div>element z zawartością. Ta zawartość w środku zwiększy wysokość <div>. Jak uzyskać wysokość „renderowaną”, jeśli nie została wyraźnie ustawiona wysokość. Oczywiście próbowałem:

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

Czy jest na to jakiś sposób? Używam jQuery, jeśli to pomaga.

BuddyJoe
źródło
zobacz tę odpowiedź stackoverflow.com/questions/19581307/…
KarSho,

Odpowiedzi:

183

Tak powinno być

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

z jQuery. Pobiera wysokość pierwszego elementu w zawiniętym zestawie jako liczbę.

Próbuję użyć

.style.height

działa tylko wtedy, gdy ustawiłeś właściwość w pierwszej kolejności. Niezbyt przydatne!

Russ Cam
źródło
1
Jedno słowo - super! Dziękujemy za udział wszystkich. Wiele dobrych informacji na ten temat. Pozwoli mi to wyśrodkować strony za pomocą CSS, ale użyję jQuery, aby poprawić całkowitą wysokość div „kontenera” bez wchodzenia w hackville CSS. Dzięki jeszcze raz.
BuddyJoe,
3
nawet jeśli NIE używasz jQuery lub cant lub nie chcesz, zdecydowanie sugeruję każdemu, kto zaimplementuje to za pomocą funkcji offsetHeight, pobierze źródło jQuery i wyszuka „wysokość”, aby znaleźć używany kod. dzieje się tam mnóstwo szalonych rzeczy!
Simon_Weaver,
1
@matejkramny - To pytanie i odpowiedź była ponad 5 lat temu . OP już używał jQuery na swojej stronie, więc zamiast ponownie wdrożyć tę samą / podobną logikę, dlaczego nie skorzystać z funkcji jQuery w jednym wierszu, która już to robi? Zgadzam się, że jQuery jest przesadzony z wieloma rzeczami i nie boję się waniliowego JS, ale gdy w bibliotece jest funkcja, która robi dokładnie to, czego potrzebujesz, wydaje się głupio nie używać jej, szczególnie z powodów z „Not Invented Here”
Russ Cam
3
@matejkramny Intencją PO podczas zadawania pytania było uzyskanie renderowanej wysokości elementu, a nie zrozumienie tego, co dzieje się w DOM i poza sceną; jeśli taki był ich zamiar, zadawali złe pytanie. Zgadzam się, że ludzie powinni mieć skłonność do rozumienia bibliotek i struktur, których używają, wiedza to potęga i tak dalej, ale czasami ktoś chce tylko odpowiedzi na konkretne pytanie. Rzeczywiście, powyższe komentarze sugerują już przejrzenie kodu jQuery, aby zrozumieć, co dzieje się za kulisami.
Russ Cam
21
W przypadku OP użycie jQuery jest prawidłową odpowiedzią. Dla reszty świata, widząc to odtąd, odpowiedź nie-jQuery jest najlepsza. Być może SO musi dostosować się do tej rzeczywistości, być może najlepiej ocenione głosy powinny być podkreślone w jakiś sposób bardziej niż te zaakceptowane.
Dimitris,
1219

Wypróbuj jedną z:

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

clientHeight obejmuje wysokość i pionowe wypełnienie.

offsetHeight obejmuje wysokość, pionowe wypełnienie i pionowe obramowania.

scrollHeight obejmuje wysokość zawartego dokumentu (byłaby większa niż tylko wysokość w przypadku przewijania), pionowe wypełnienie i pionowe obramowania.

strager
źródło
3
Dzięki, nie wiedziałem o tej nieruchomości. Jest również kompatybilny z IE8 +.
lyubeto
Jestem zakłopotany znaczeniem clientHeight. Mam element div, który zawiera kilka elementów p, a zawartość wykracza daleko poza widoczny obszar przeglądarki w dół. Oczekiwałem, że clientHeight poda renderowaną wysokość, a scrollHeight, aby podać pełną długość. Ale są prawie równe (różnią się tylko marginesem, wypełnieniem itp.).
bahti
10
@bahti, chyba że sama ma ograniczoną wysokość i przepełnienie: ukryte lub jakąś formę przepełnienia: przewijanie, element rozszerzy się (w twoim widoku lub nie), aby pokazać całą zawartość oraz scrollHeight i clientHeight będą równe.
Ulad Kasach
4
Świetna odpowiedź, ale logicznie granice wpływające na wysokość elementu to górne i dolne granice, które są poziome. Ta odpowiedź nazywa je „pionowymi granicami”. Pomyślałem, że
zrzucę
1
Z tego co wiem, .clientWidth/.clientHeight NIE dołączaj szerokości przewijania, jeśli przewijanie jest pokazane. Jeśli chcesz uwzględnić szerokość przewijania, możesz użyć element.getBoundingClientRect().width zamiast tego
Dmitry Gonchar
151

NIE JQUERY, ponieważ elem.style.heightw górnej części tych odpowiedzi było kilka linków ...

WYSOKOŚĆ WEWNĘTRZNA:
https://developer.mozilla.org/en-US/docs/Web/API/Element.clientHeight

document.getElementById(id_attribute_value).clientHeight;

WYSOKOŚĆ ZEWNĘTRZNA:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.offsetHeight

document.getElementById(id_attribute_value).offsetHeight; 

Lub jedno z moich ulubionych odniesień: http://youmightnotneedjquery.com/

Jason Lydon
źródło
49

Możesz użyć .outerHeight()do tego celu.

Zapewni to pełną renderowaną wysokość elementu. Nie musisz też ustawiać żadnego css-heightelementu. Dla zachowania ostrożności można zachować automatyczną wysokość, aby można ją było renderować według wysokości zawartości.

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

Aby uzyskać przejrzysty widok tej funkcji, możesz przejść na stronę jQuery lub szczegółowy post tutaj .

usunie różnicę między .height()/ innerHeight()/outerHeight()

otwarty i bezpłatny
źródło
1
Dzięki. Podczas pracy z pływakami miałem wiele problemów z automatycznym wzrostem wysokości, ale wtedy byłem niedoświadczony. Zasadniczo nie ustawiałem wysokości, z wyjątkiem skryptu złożonego układu, w którym początkowo wyczyściłem pole, ale ustawiłem, aby było równe dla każdego bloku (Div), który kończy się na tej samej górze. Nawet różnica jednego bloku między blokami może zepsuć układ podczas zmiany rozmiaru okien.
DHorse
1
BTW, myślę, że offset ma pewne zastosowania zależne od wersji przeglądarki dotyczące marginesów, które to eliminuje.
DHorse
2
Pytanie nie wymaga jQuery. Ugh.
dthree
1
@dthree Myślę, że wyraźnie wspomniał, że używa jQuery. (również zawarte w tagach) :)
otwarte i darmowe
44

Używam tego, aby uzyskać wysokość elementu (zwraca liczbę zmiennoprzecinkową) :

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

Działa również, gdy korzystasz z wirtualnego DOM . Używam go w Vue w następujący sposób:

this.$refs['some-ref'].getBoundingClientRect().height
Daantje
źródło
1
getBoundingClientRect (). wysokość zwraca liczbę zmiennoprzecinkową (podczas gdy inni zwracają liczbę całkowitą), ładnie :)
Ari
31
style = window.getComputedStyle(your_element);

to po prostu: style.height

Feiteira
źródło
14

Zdecydowanie użyj

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

lub

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

Podaję to jako dodatkową odpowiedź, ponieważ jest kilka ważnych rzeczy, których właśnie się nauczyłem.

Prawie wpadłem w pułapkę użycia offsetHeight. To jest to, co się stało :

  • Użyłem starej dobrej sztuczki polegającej na użyciu debugera do „obserwowania” właściwości mojego elementu
  • Widziałem, która z nich ma wartość zbliżoną do wartości, której się spodziewałem
  • To było offsetHeight - więc tego użyłem.
  • Potem zdałem sobie sprawę, że to nie działa z ukrytym DIV
  • Próbowałem ukryć się po obliczeniu maxHeight, ale wyglądało to niezdarnie - wpadłem w bałagan.
  • Przeprowadziłem wyszukiwanie - odkryłem jQuery.height () - i użyłem go
  • ustalona wysokość () działa nawet na ukrytych elementach
  • dla zabawy sprawdziłem implementację wysokości / szerokości jQuery

Oto tylko jego część:

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

Tak, patrzy na ZARÓWNO i przesunięcie. Jeśli to się nie powiedzie, wygląda jeszcze dalej, biorąc pod uwagę problemy ze zgodnością przeglądarki i css. Innymi słowy STUFF NIE PIELĘGNUJE - lub chcę.

Ale nie muszę. Dzięki jQuery!

Morał tej historii: jeśli jQuery ma metodę na coś, to prawdopodobnie z dobrego powodu, prawdopodobnie związanego z kompatybilnością.

Jeśli nie przeczytałeś ostatnio listy metod jQuery , sugeruję, abyś rzucił okiem.

Simon_Weaver
źródło
Widziałem twój inny komentarz na poziomie pytania. Jestem sprzedawany na jQuery. Byłem przez chwilę. Ale to przypieczętowało umowę. Jestem zakochany w tym, że ta prosta sprawa rozwiąże dla mnie setki problemów z układem (głównie na stronach intranetowych, w których wiem, że JavaScript jest uruchomiony).
BuddyJoe,
13
document.querySelector('.project_list_div').offsetHeight;
Ritwik
źródło
4
dodaj wyjaśnienie do swojego rozwiązania
Freelancer
następnie offsetHeight
Ritwik
6
Ta właściwość zaokrągli wartość do liczby całkowitej . Jeśli potrzebujesz wartości zmiennoprzecinkowej , użyjelem.getBoundingClientRect().height
Penny Liu
12

Stworzyłem prosty kod, który nawet nie potrzebuje JQuery i prawdopodobnie pomoże niektórym ludziom. Pobiera całkowitą wysokość „ID1” po załadowaniu i używa go na „ID2”

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

Następnie po prostu ustaw ciało, aby je załadować

<body onload='anyName()'>
Robuske
źródło
Jest to przydatne i używam czegoś podobnego w bardziej złożonym kodzie.
DHorse
10

Hm, możemy uzyskać geometrię elementu ...

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

Co powiesz na ten zwykły JS?

Thomas Ludewig
źródło
1
var geometry; geometry={};może po prostu byćvar geometry={};
Mark Schultheiss
10

Myślę, że najlepszym sposobem na zrobienie tego w 2020 roku jest użycie zwykłego js i getBoundingClientRect().height;

Oto przykład

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

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

Oprócz heighttego, mamy również dostęp do wielu innych rzeczy na temat div.

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

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

Oneezy
źródło
8

Czy to jest odpowiedź?

„Jeśli musisz coś obliczyć, ale nie chcesz tego pokazać, ustaw element na visibility:hiddeniposition:absolute dodaj go do drzewa DOM, uzyskaj offsetHeight i usuń go. (To właśnie robi biblioteka prototypowa za liniami podczas ostatniego sprawdzania)”.

Mam ten sam problem z wieloma elementami. Na stronie nie ma jQuery ani prototypu, ale jestem zwolennikiem pożyczenia tej techniki, jeśli działa. Jako przykład niektórych rzeczy, które nie działały, a następnie tego, co zrobiłem, mam następujący kod:

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

który w zasadzie próbuje wszystkiego i tylko po to, aby uzyskać zerowy wynik. ClientHeight bez wpływu. Z elementami problemowymi zwykle dostaję NaN w Bazie i zero w wysokości Przesunięcia i Przewijania. Następnie spróbowałem dodać rozwiązanie DOM i clientRects, aby sprawdzić, czy to działa tutaj.

29 czerwca 2011 r. Rzeczywiście zaktualizowałem kod, aby spróbować zarówno dodać do DOM, jak i clientHeight z lepszymi wynikami niż się spodziewałem.

1) clientHeight było również 0.

2) Dom rzeczywiście dał mi wzrost, który był świetny.

3) ClientRects zwraca wynik prawie identyczny z techniką DOM.

Ponieważ dodane elementy mają płynny charakter, po dodaniu do innego pustego elementu DOM Temp są renderowane zgodnie z szerokością tego kontenera. Dziwnie się to robi, bo jest o 30 pikseli krótsze niż ostatecznie.

Dodałem kilka migawek, aby zilustrować, w jaki sposób wysokość jest obliczana inaczej. Blok menu renderowany normalnie Blok menu dodany do elementu DOM Temp

Różnice wysokości są oczywiste. Z pewnością mógłbym dodać pozycjonowanie bezwzględne i ukryte, ale jestem pewien, że to nie przyniesie efektu. Nadal byłem przekonany, że to nie zadziała!

(I dygresuję dalej) Wysokość wychodzi (renderuje) poniżej rzeczywistej renderowanej wysokości. Można temu zaradzić, ustawiając szerokość elementu DOM Temp w celu dopasowania do istniejącego elementu nadrzędnego i teoretycznie można to zrobić dość dokładnie. Nie wiem też, co by się stało z ich usunięcia i dodania z powrotem do ich istniejącej lokalizacji. Gdy dotarli za pomocą techniki innerHTML, będę szukał tego innego podejścia.

* JEDNAK * Nie było to konieczne. W rzeczywistości działał zgodnie z reklamą i zwrócił prawidłową wysokość !!!

Kiedy udało mi się ponownie wyświetlić menu, zadziwiająco DOM zwrócił prawidłową wysokość dla układu płynu na górze strony (279 pikseli). Powyższy kod używa również getClientRects, które zwracają 280px.

Ilustruje to poniższa migawka (pobrana z Chrome po uruchomieniu).
wprowadź opis zdjęcia tutaj

Teraz nie mam pojęcia, dlaczego ta prototypowa sztuczka działa, ale wydaje się, że tak. Alternatywnie działa również getClientRects.

Podejrzewam, że przyczyną wszystkich problemów z tymi konkretnymi elementami było użycie innerHTML zamiast appendChild, ale w tym momencie jest to czysta spekulacja.

DHorse
źródło
6

offsetHeight, zazwyczaj.

Jeśli musisz coś obliczyć, ale go nie wyświetlasz, ustaw element na visibility:hiddeni position:absolutedodaj go do drzewa DOM, pobierz offsetHeighti usuń. (To właśnie robi biblioteka prototypów za scenami, kiedy ostatnio sprawdzałem).

htoip
źródło
ciekawy. nigdy nie sprawdzałem prototypu. jakiś pomysł, dlaczego jQuery nie robi tego za kulisami?
Simon_Weaver
Widziałem to, gdy miałem trudności i przetestowałem tę technikę i działała całkiem dobrze w zwykłym JavaScript
DHorse
5

Czasami offsetHeight zwróci zero, ponieważ utworzony element nie został jeszcze zrenderowany w Dom. Napisałem tę funkcję dla takich okoliczności:

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
źródło
musisz sklonować element, w przeciwnym razie zostanie on całkowicie usunięty z domeny, wygląda na to, że tak się stanie.
punkbit
Ten kod nie jest przeznaczony do przechowywania elementu w DOM. Ma to na celu krótkie umieszczenie go w DOM (wystarczająco długo, aby go wyrenderować i uzyskać wysokość), a następnie wyjmuje. Możesz później umieścić element w domku gdzie indziej (wiedząc, jaka będzie jego wysokość, zanim to zrobisz). Zwróć uwagę na nazwę funkcji „getHeight”; to wszystko, co kod zamierza zrobić.
Lonnie Best
@punkbit: Rozumiem, co masz na myśli. Twój element jest już w domenie. Kod, który napisałem, dotyczy elementu, którego jeszcze nie ma w DOM. Klonowanie byłoby lepsze, jak mówisz, ponieważ nie miałoby znaczenia, czy element jest w domenie, czy nie.
Lonnie Best
@punkbit: Zmodyfikowałem klonowanie przy użyciu kodu, ale go nie testowałem.
Lonnie Best
tak, o to mi chodziło. Wydawało mi się, że mówi „element” dla istniejącego elementu w DOM. Ale wszystko dobrze! Nie zrozumcie tego źle.
punkbit
4

Jeśli już używasz jQuery, najlepszym wyborem jest .outerHeight()lub .height(), jak już wspomniano.

Bez jQuery możesz sprawdzić używane rozmiary okien i dodać różne wypełnienia + obramowania + wysokość klienta lub możesz użyć getComputedStyle :

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

h będzie teraz ciągiem takim jak „53,825px”.

I nie mogę znaleźć referencji, ale myślę, że słyszałem, że getComputedStyle()może być drogi, więc prawdopodobnie nie jest to coś, co chcesz wywoływać przy każdym window.onscrollzdarzeniu (ale wtedy nie jest to również jQuery height()).

chbrown
źródło
Po uzyskaniu wysokości getComputedStyle, użyj, parseInt(h, 10)aby uzyskać liczbę całkowitą do obliczeń.
RhodanV5500
2

Z MooTools :

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

kwcto
źródło
1

Jeśli dobrze zrozumiałem twoje pytanie, być może coś takiego pomogłoby:

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
źródło
-4

Czy konkretnie ustawiłeś wysokość w css? Jeśli nie, musisz użyć offsetHeight;zamiastheight

var h = document.getElementById('someDiv').style.offsetHeight;
Steerpike
źródło
8
offsetHeight jest właściwością samego elementu, a nie jego stylu.
Shog9