Jak pobrać rzeczywistą szerokość i wysokość elementu HTML?

892

Załóżmy, że mam coś <div>, co chciałbym wyśrodkować na ekranie przeglądarki (rzutnia). Aby to zrobić, muszę obliczyć szerokość i wysokość <div>elementu.

Czego powinienem użyć? Podaj informacje na temat zgodności przeglądarki.

snortasprocket
źródło
9
Należy pamiętać, że uzyskanie wysokości elementu za pomocą dowolnej metody ma zawsze wpływ na wydajność, ponieważ powoduje, że przeglądarka ponownie oblicza pozycję wszystkich elementów na stronie (ponowne wlanie). Dlatego unikaj robienia tego za dużo. Kasy tej listy dla jakiego rodzaju rzeczy wywołać reflow.
Marcelo Lazaroni,

Odpowiedzi:

1285

Powinieneś użyć właściwości .offsetWidthi .offsetHeight. Zauważ, że należą do elementu, a nie .style.

var width = document.getElementById('foo').offsetWidth;

Funkcja.getBoundingClientRect() zwraca wymiary i położenie elementu jako liczby zmiennoprzecinkowe po wykonaniu transformacji CSS.

> console.log(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,
}
Greg
źródło
174
Strzec się! offsetHeight / offsetWidth może zwrócić 0, jeśli ostatnio dokonałeś pewnych modyfikacji DOM elementu. Może być konieczne wywołanie tego kodu w wywołaniu setTimeout po zmodyfikowaniu elementu.
Dan Fabulich
37
Dokumentacja na temat : .offsetWidthi developer.mozilla.org/en/Determining_the_dimensions_of_elements.offsetHeight
Denilson Sá Maia
30
W jakich okolicznościach zwraca 0?
Gepard
46
@JDandChips: offsetWidthwyniesie 0, jeśli element jest display:none, podczas gdy obliczone widthmogą nadal mieć dodatnią wartość w tym przypadku. visibility:hiddennie wpływa na offsetWidth.
MrWhite
20
@Supuhstar oba mają różne znaczenia. offsetWidthzwraca „całe” pole zawierające treść, dopełnienie i obramowania; podczas gdy clientWidthzwraca rozmiar samego pola zawartości (więc będzie miał mniejszą wartość, ilekroć element będzie miał niezerowe wypełnienie i / lub ramkę). (zmodyfikowany dla jasności)
Edurne Pascual
200

Spójrz na Element.getBoundingClientRect().

Metoda ta zwraca obiekt zawierający width, heighti pewne inne przydatne wartości:

{
    width: 960,
    height: 71,
    top: 603,
    bottom: 674,
    left: 360,
    right: 1320
}

Na przykład:

var element = document.getElementById('foo');
var positionInfo = element.getBoundingClientRect();
var height = positionInfo.height;
var width = positionInfo.width;

Wierzę, że to nie ma kwestii, które .offsetWidthi .offsetHeightzrobić gdzie czasami powrócić 0(omówione w komentarzach tutaj )

Inną różnicą jest to, że getBoundingClientRect()mogą zwracać ułamkowe piksele, gdzie .offsetWidthi .offsetHeightzaokrąglą do najbliższej liczby całkowitej.

Uwaga IE8 : getBoundingClientRectnie zwraca wysokości i szerokości w IE8 i niższych. *

Jeśli musisz obsługiwać IE8, użyj .offsetWidthi .offsetHeight:

var height = element.offsetHeight;
var width = element.offsetWidth;

Warto zauważyć, że obiekt zwracany tą metodą nie jest tak naprawdę normalnym obiektem. Jego właściwości nie są wyliczalne (więc na przykład Object.keysnie działają od razu po wyjęciu z pudełka).

Więcej informacji na ten temat tutaj: Jak najlepiej przekonwertować ClientRect / DomRect na zwykły obiekt

Odniesienie:

Zach Lysobey
źródło
8
getboundingClientRect () powróci rzeczywistą szerokość i wysokość elementów skalowane poprzez css zaś offsetHeighti offsetWidthnie.
Łukasz
66

UWAGA : ta odpowiedź została napisana w 2008 roku. W tamtym czasie najlepszym rozwiązaniem dla wielu przeglądarek było użycie jQuery. Zostawiam tutaj odpowiedź dla potomnych, a jeśli używasz jQuery, jest to dobry sposób na zrobienie tego. Jeśli używasz innego frameworka lub czystego JavaScriptu, prawdopodobnie jest to akceptowana odpowiedź.

Jak jQuery 1.2.6 można użyć jednej z podstawowych funkcji CSS , heighti width(lub outerHeighti outerWidth, w razie potrzeby).

var height = $("#myDiv").height();
var width = $("#myDiv").width();

var docHeight = $(document).height();
var docWidth = $(document).width();
tvanfosson
źródło
45

Na wszelki wypadek przydaje się każdemu, umieszczam pole tekstowe, przycisk i div wszystkie z tym samym 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>

Próbowałem w chrome, firefox i ie-edge, próbowałem z jquery i bez, i próbowałem z i bez box-sizing:border-box. Zawsze z<!DOCTYPE html>

Wyniki:

                                                               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
Graham
źródło
1
Żeby było jasne ... czy któraś z tych przeglądarek robi coś innego od siebie? Nie mogę znaleźć żadnych różnic ... Ponadto, nie jestem w dół głosowania (jeszcze), ale to nie naprawdę bezpośrednio odpowiedzieć na pytanie, choć może to być łatwo editted zrobić.
Zach Lysobey,
1
Nie miało na celu udzielenia odpowiedzi na pytanie - na już udzielono odpowiedzi. Tylko kilka przydatnych informacji i tak, wszystkie główne najnowsze wersje przeglądarek zgadzają się na te wartości - co jest dobrą rzeczą.
Graham
3
Cóż ... jeśli twoim celem nie jest udzielenie odpowiedzi na pytanie, to tak naprawdę nie należy tutaj (jako „odpowiedź”). Zastanowiłbym się nad umieszczeniem tego w jakimś zewnętrznym zasobie (być może w GitHub lub postu na blogu) i połączenie go w komentarzu do pierwotnego pytania lub jednej z odpowiedzi.
Zach Lysobey
21
@ZachLysobey Istnieją wyjątki od każdej reguły - i jest to fajna, przydatna rzecz do zobaczenia.
Dan Nissenbaum
16

Według MDN: Określanie wymiarów elementów

offsetWidthi offsetHeightzwraca „całkowitą ilość miejsca, jaką zajmuje element, w tym szerokość widocznej zawartości, paski przewijania (jeśli istnieją), dopełnienie i obramowanie”

clientWidthi clientHeightzwróć „ile miejsca zajmuje faktycznie wyświetlana treść, w tym wypełnienie, ale bez obramowania, marginesów lub pasków przewijania”

scrollWidthi scrollHeightzwróć „rzeczywisty rozmiar treści, bez względu na to, ile jest obecnie widoczna”

Zależy to zatem od tego, czy mierzona zawartość będzie poza bieżącym widocznym obszarem.

Harlem Wiewiórka
źródło
5

Musisz go tylko obliczyć dla IE7 i starszych (i tylko wtedy, gdy treść nie ma ustalonego rozmiaru). Sugeruję użycie komentarzy warunkowych HTML, aby ograniczyć włamanie do starych IE, które nie obsługują CSS2. W przypadku wszystkich innych przeglądarek użyj tego:

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

To idealne rozwiązanie. Wyśrodkowuje <div>dowolny rozmiar i zawija go do rozmiaru zawartości.

Kornel
źródło
3

Łatwo jest modyfikować style elementów, ale trudno jest odczytać wartość.

JavaScript nie może odczytać żadnej właściwości stylu elementu (elem.style) pochodzącej z css (wewnętrznego / zewnętrznego), chyba że użyjesz wbudowanego wywołania metody getComputedStyle w javascript.

getComputedStyle (element [, pseudo])

Element: element do odczytu wartości.
pseudo: pseudoelement, jeśli jest wymagany, na przykład :: przed. Pusty ciąg lub brak argumentu oznacza sam element.

Wynikiem jest obiekt o właściwościach stylu, taki jak elem.style, ale teraz w odniesieniu do wszystkich klas css.

Na przykład tutaj styl nie widzi marginesu:

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

Zmodyfikowano więc kod javaScript, aby zawierał getComputedStyle elementu, który ma uzyskać szerokość / wysokość lub inny atrybut

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.log(element);
        console.log(width);
    }

}

Obliczone i rozwiązane wartości

W CSS istnieją dwie koncepcje:

Obliczona wartość stylu jest wartością po zastosowaniu wszystkich reguł CSS i dziedziczeniu CSS w wyniku kaskady CSS. Może wyglądać jak wysokość: 1 em lub rozmiar czcionki: 125%.

Rozwiązana wartość stylu to ta, która ostatecznie została zastosowana do elementu. Wartości takie jak 1em lub 125% są względne. Przeglądarka przyjmuje obliczoną wartość i sprawia, że ​​wszystkie jednostki są stałe i bezwzględne, na przykład: wysokość: 20 pikseli lub rozmiar czcionki: 16 pikseli. Dla właściwości geometrii rozstrzygnięte wartości mogą mieć zmiennoprzecinkowe, takie jak szerokość: 50,5 pikseli.

Dawno, dawno temu getComputedStyle został stworzony, aby uzyskać obliczone wartości, ale okazało się, że rozwiązane wartości są znacznie wygodniejsze i standard się zmienił.
W dzisiejszych czasach getComputedStyle faktycznie zwraca rozstrzygniętą wartość właściwości.

Proszę zanotować:

getComputedStyle wymaga pełnej nazwy właściwości

Zawsze należy pytać o dokładną właściwość, taką jak paddingLeft lub wysokość lub szerokość. W przeciwnym razie poprawny wynik nie jest gwarantowany.

Na przykład, jeśli istnieją właściwości paddingLeft / paddingTop, to co powinniśmy uzyskać dla getComputedStyle (elem) .padding? Nic, a może „wygenerowana” wartość ze znanych wypełnień? Nie ma tutaj standardowej reguły.

Istnieją inne niespójności. Na przykład niektóre przeglądarki (Chrome) pokazują 10px w poniższym dokumencie, a niektóre z nich (Firefox) - nie:

<style>
  body {
    margin: 30px;
    height: 900px;
  }
</style>
<script>
  let style = getComputedStyle(document.body);
  alert(style.margin); // empty string in Firefox
</script>

aby uzyskać więcej informacji https://javascript.info/styles-and-classes

Lekens
źródło
1

element.offsetWidth i element.offsetHeight powinny zrobić, jak sugerowano w poprzednim poście.

Jeśli jednak chcesz wyśrodkować zawartość, istnieje na to lepszy sposób. Zakładając, że używasz xhtml strict DOCTYPE. ustaw margines: 0, właściwość auto i wymaganą szerokość w pikselach do tagu body. Treść zostaje wyśrodkowana w stosunku do strony.

questzen
źródło
1
Myślę, że chce również wyśrodkować go w pionie, co jest właściwym bólem w CSS, chyba że możesz spełnić określone kryteria (np. Treść o znanej wielkości)
Greg,
1

... wydaje się, że CSS pomaga umieścić div na środku ...

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

możesz także użyć tego kodu:

var divID = document.getElementById("divid");

var h = divID.style.pixelHeight;
Sergio
źródło
1
Hmm, działa w Chrome i IE9, nie działa w Firefoksie. Czy to działa tylko w przypadku niektórych typów dokumentów?
BrainSlugs83
1
pixelHeight to wynalazek Internet Explorera, którego nie należy już stosować stackoverflow.com/q/17405066/2194590
HolgerJeromin
0

jeśli chcesz wyśrodkować go w porcie wyświetlania przeglądarki; możesz to osiągnąć tylko za pomocą CSS

yourSelector {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
} 
tdjprog
źródło
-2

Oto kod WKWebView, który określa wysokość określonego elementu Dom (nie działa poprawnie dla całej strony)

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 {

        }
    }
}
Aleksiej Mazurenko
źródło
dla jasności, to jest swiftkod iOS , prawda? Nie JavaScript. Zastrzegam sobie zdanie negatywne (b / c może to być naprawdę przydatne), ale pamiętaj, że to nie odpowiada na pytanie i prawdopodobnie byłoby bardziej odpowiednie w przypadku innego, specyficznego dla iOS pytania. Jeśli jeszcze nie istnieje, może zastanów się nad pytaniem i odpowiedzią na to pytanie.
Zach Lysobey
-3

Jeśli offsetWidth zwraca wartość 0, można uzyskać właściwość szerokości stylu elementu i wyszukać ją dla liczby. „100px” -> 100

/\d*/.exec(MyElement.style.width)

Arko
źródło