Bagaimana cara mengambil lebar dan tinggi sebenarnya elemen HTML?

895

Misalkan saya memiliki <div>yang saya ingin pusatkan di tampilan browser (viewport). Untuk melakukannya, saya perlu menghitung lebar dan tinggi<div> elemen.

Apa yang harus saya gunakan? Harap sertakan informasi tentang kompatibilitas browser.

snortasprocket
sumber
9
Perlu diingat bahwa mendapatkan ketinggian elemen melalui metode apa pun selalu memiliki dampak kinerja karena membuat browser menghitung ulang posisi semua elemen di halaman (reflow). Karena itu, hindari melakukannya terlalu banyak. Periksa daftar ini untuk mengetahui hal-hal apa yang memicu reflow.
Marcelo Lazaroni

Jawaban:

1288

Anda harus menggunakan .offsetWidthdan .offsetHeightproperti. Perhatikan bahwa itu milik elemen, bukan .style.

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

Fungsi.getBoundingClientRect() mengembalikan dimensi dan lokasi elemen sebagai angka floating-point setelah melakukan transformasi 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
sumber
174
Waspadalah! offsetHeight / offsetWidth dapat mengembalikan 0 jika Anda telah melakukan modifikasi DOM tertentu untuk elemen baru-baru ini. Anda mungkin harus memanggil kode ini dalam panggilan setTimeout setelah Anda memodifikasi elemen.
Dan Fabulich
37
Dokumentasi tentang .offsetWidthdan .offsetHeight: developer.mozilla.org/en/Determining_the_dimensions_of_elements
Denilson Sá Maia
31
Dalam keadaan apa ia mengembalikan 0?
Cheetah
46
@JDandChips: offsetWidthakan menjadi 0 jika elemennya adalah display:none, sedangkan yang dikomputasi widthmungkin masih memiliki nilai positif dalam contoh ini. visibility:hiddentidak mempengaruhi offsetWidth.
MrWhite
21
@Supuhstar keduanya memiliki arti yang berbeda. offsetWidthmengembalikan kotak "keseluruhan" termasuk konten, padding, dan perbatasan; sementara clientWidthmengembalikan ukuran kotak konten saja (sehingga akan memiliki nilai yang lebih kecil setiap kali elemen memiliki padding dan / atau perbatasan yang tidak nol). (mod diedit untuk kejelasan)
Edurne Pascual
200

Lihatlah Element.getBoundingClientRect().

Metode ini akan mengembalikan objek yang berisi width, heightdan beberapa nilai lain yang bermanfaat:

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

Sebagai contoh:

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

Saya percaya ini tidak memiliki masalah itu .offsetWidthdan .offsetHeightlakukan di mana mereka kembali 0(seperti yang dibahas dalam komentar di sini )

Perbedaan lainnya adalah getBoundingClientRect()dapat mengembalikan piksel fraksional, di mana .offsetWidthdan .offsetHeightakan membulatkan ke bilangan bulat terdekat.

Catatan IE8 : getBoundingClientRecttidak mengembalikan tinggi dan lebar pada IE8 dan di bawah. *

Jika Anda harus mendukung IE8, gunakan .offsetWidthdan .offsetHeight:

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

Perlu dicatat bahwa Objek yang dikembalikan oleh metode ini sebenarnya bukan objek yang normal . Properti tidak dapat dihitung (jadi, misalnya,Object.keys tidak bekerja di luar kotak.)

Info lebih lanjut tentang ini di sini: Cara terbaik untuk mengubah ClientRect / DomRect menjadi Obyek biasa

Referensi:

Zach Lysobey
sumber
8
getboundingClientRect () akan mengembalikan lebar aktual dan tinggi elemen yang diskalakan melalui css sedangkan offsetHeightdan offsetWidthtidak.
Luke
66

CATATAN : jawaban ini ditulis pada tahun 2008. Pada saat itu solusi lintas-browser terbaik bagi kebanyakan orang adalah menggunakan jQuery. Saya meninggalkan jawaban di sini untuk anak cucu dan, jika Anda menggunakan jQuery, ini adalah cara yang baik untuk melakukannya. Jika Anda menggunakan kerangka kerja lain atau JavaScript murni, jawaban yang diterima mungkin adalah jalan yang harus ditempuh.

Pada jQuery 1.2.6 Anda dapat menggunakan salah satu fungsi inti CSS , heightdan width(atau outerHeightdan outerWidth, jika sesuai).

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

var docHeight = $(document).height();
var docWidth = $(document).width();
tvanfosson
sumber
45

Kalau-kalau berguna bagi siapa pun, saya meletakkan kotak teks, tombol dan div semua dengan css yang sama:

width:200px;
height:20px;
border:solid 1px #000;
padding:2px;

<input id="t" type="text" />
<input id="b" type="button" />
<div   id="d"></div>

Saya mencobanya dengan chrome, firefox dan ie-edge, saya mencoba dengan jquery dan tanpa, dan saya mencobanya dengan dan tanpa box-sizing:border-box. Selalu dengan<!DOCTYPE html>

Hasil:

                                                               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
sumber
1
Untuk memperjelas ... apakah ada browser yang melakukan sesuatu yang berbeda dari satu sama lain? Saya tidak dapat menemukan perbedaan ... Juga, saya belum memilih, tapi ini tidak benar - benar langsung menjawab pertanyaan, meskipun bisa dengan mudah diedit untuk melakukannya.
Zach Lysobey
1
Tidak ditujukan untuk menjawab pertanyaan - sudah dijawab. Hanya beberapa informasi bermanfaat dan ya, semua browser versi terbaru utama setuju pada nilai-nilai ini - yang merupakan hal yang baik.
Graham
3
Nah ... jika niat Anda bukan untuk menjawab pertanyaan, maka ini bukan milik di sini (sebagai "jawaban"). Saya akan mempertimbangkan untuk menempatkan ini di beberapa sumber daya eksternal (mungkin inti GitHub, atau posting blog) dan menghubungkannya dalam komentar pada Pertanyaan asli atau salah satu jawaban.
Zach Lysobey
21
@ZachLysobey Ada pengecualian untuk setiap aturan - dan ini adalah hal yang keren dan berguna untuk dilihat.
Dan Nissenbaum
16

Menurut MDN: Menentukan dimensi elemen

offsetWidthdan offsetHeightkembalikan "jumlah total ruang yang ditempati elemen, termasuk lebar konten yang terlihat, scrollbar (jika ada), padding, dan border"

clientWidthdan clientHeightkembalikan "seberapa banyak ruang yang digunakan untuk konten yang ditampilkan, termasuk padding tetapi tidak termasuk perbatasan, margin, atau scrollbar"

scrollWidthdan scrollHeightkembalikan "ukuran sebenarnya dari konten, terlepas dari berapa banyak dari itu saat ini terlihat"

Jadi itu tergantung pada apakah konten yang diukur diharapkan keluar dari area yang dapat dilihat saat ini.

HarlemSquirrel
sumber
5

Anda hanya perlu menghitungnya untuk IE7 dan yang lebih lama (dan hanya jika konten Anda tidak memiliki ukuran tetap). Saya sarankan menggunakan komentar kondisional HTML untuk membatasi retas ke IE lama yang tidak mendukung CSS2. Untuk semua browser lain gunakan ini:

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

Ini solusi sempurna. Ia memusatkan <div>ukuran apa pun, dan menyusutkannya ke ukuran kontennya.

Kornel
sumber
3

Sangat mudah untuk memodifikasi gaya elemen tetapi agak sulit untuk membaca nilainya.

JavaScript tidak dapat membaca properti gaya elemen (elem.style) yang berasal dari css (internal / eksternal) kecuali Anda menggunakan metode panggilan internal getComputedStyle di javascript.

getComputedStyle (elemen [, pseudo])

Elemen: Elemen untuk membaca nilai untuk.
pseudo: Elemen pseudo jika diperlukan, misalnya :: sebelumnya. String kosong atau tanpa argumen berarti elemen itu sendiri.

Hasilnya adalah objek dengan properti style, seperti elem.style, tapi sekarang dengan memperhatikan semua kelas css.

Misalnya, di sini style tidak melihat margin:

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

Jadi modifikasi kode javaScript Anda untuk memasukkan getComputedStyle dari elemen yang ingin Anda dapatkan lebar / tinggi atau atribut lainnya

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

}

Nilai yang dihitung dan diselesaikan

Ada dua konsep dalam CSS:

Nilai gaya terkomputasi adalah nilai setelah semua aturan CSS dan pewarisan CSS diterapkan, sebagai hasil dari kaskade CSS. Ini bisa terlihat seperti tinggi: 1em atau ukuran font: 125%.

Nilai gaya yang diselesaikan adalah yang akhirnya diterapkan ke elemen. Nilai-nilai seperti 1em atau 125% adalah relatif. Browser mengambil nilai yang dihitung dan membuat semua unit tetap dan absolut, misalnya: tinggi: 20px atau ukuran font: 16px. Untuk properti geometri, nilai yang diselesaikan mungkin memiliki titik apung, seperti lebar: 50,5px.

Dulu getComputedStyle telah dibuat untuk mendapatkan nilai yang dihitung, tetapi ternyata nilai yang diselesaikan jauh lebih nyaman, dan standar berubah.
Jadi saat ini getComputedStyle benar-benar mengembalikan nilai yang diselesaikan dari properti.

Tolong dicatat:

getComputedStyle membutuhkan nama properti lengkap

Anda harus selalu menanyakan properti yang Anda inginkan, seperti paddingLeft atau tinggi atau lebar. Kalau tidak, hasil yang benar tidak dijamin.

Misalnya, jika ada properti paddingLeft / paddingTop, lalu apa yang harus kita dapatkan untuk getComputedStyle (elem) .padding? Tidak ada, atau mungkin nilai "yang dihasilkan" dari paddings yang dikenal? Tidak ada aturan standar di sini.

Ada ketidakkonsistenan lain. Sebagai contoh, beberapa browser (Chrome) menunjukkan 10px pada dokumen di bawah ini, dan beberapa di antaranya (Firefox) - jangan:

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

untuk informasi lebih lanjut https://javascript.info/styles-and-classes

Lekens
sumber
1

element.offsetWidth dan element.offsetHeight harus dilakukan, seperti yang disarankan dalam posting sebelumnya.

Namun, jika Anda hanya ingin memusatkan konten, ada cara yang lebih baik untuk melakukannya. Asumsikan Anda menggunakan xhtml DOCTYPE ketat. atur margin: 0, properti otomatis dan lebar yang diperlukan dalam px ke tag body. Konten mendapat pusat selaras ke halaman.

questzen
sumber
1
Saya pikir dia ingin memusatkannya secara vertikal juga, yang merupakan rasa sakit yang tepat dengan CSS kecuali jika Anda dapat memenuhi beberapa kriteria tertentu (misalnya konten ukuran diketahui)
Greg
1

... tampaknya CSS membantu menempatkan div di tengah ...

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

Anda juga dapat menggunakan kode ini:

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

var h = divID.style.pixelHeight;
Sergio
sumber
1
Hmm, berfungsi di Chrome dan IE9, tampaknya tidak berfungsi di Firefox. Apakah hanya berfungsi untuk tipe dokumen tertentu?
BrainSlugs83
1
pixelHeight adalah penemuan Internet Explorer yang tidak boleh digunakan lagi stackoverflow.com/q/17405066/2194590
HolgerJeromin
0

jika Anda perlu memusatkannya di port tampilan browser; Anda dapat mencapainya hanya dengan CSS

yourSelector {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
} 
tdjprog
sumber
-2

Berikut ini adalah kode untuk WKWebView yang menentukan ketinggian elemen Dom tertentu (tidak berfungsi dengan baik untuk seluruh halaman)

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 {

        }
    }
}
Aleksey Mazurenko
sumber
hanya untuk menjadi jelas, ini swiftkode iOS , kan? Bukan JavaScript. Saya menahan downvote (b / c ini mungkin sebenarnya cukup berguna) tetapi harap dicatat bahwa ini tidak menjawab pertanyaan, dan kemungkinan akan lebih cocok untuk pertanyaan lain, khusus iOS. Jika belum ada, mungkin pertimbangkan untuk bertanya dan menjawab sendiri.
Zach Lysobey
-3

Jika offsetWidth mengembalikan 0, Anda bisa mendapatkan properti lebar gaya elemen dan mencarinya untuk nomor. "100px" -> 100

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

Arko
sumber