ฉันจะดึงความกว้างและความสูงที่แท้จริงขององค์ประกอบ HTML ได้อย่างไร


893

สมมติว่าฉันมีสิ่ง<div>ที่ฉันต้องการที่จะศูนย์ในการแสดงผลของเบราว์เซอร์ (วิวพอร์ต) หากต้องการทำเช่นนั้นฉันต้องคำนวณความกว้างและความสูงของ<div>องค์ประกอบ

ฉันควรใช้อะไร โปรดระบุข้อมูลเกี่ยวกับความเข้ากันได้ของเบราว์เซอร์


9
โปรดทราบว่าการเพิ่มความสูงขององค์ประกอบผ่านวิธีการใด ๆจะมีผลกระทบต่อประสิทธิภาพเสมอเพราะจะทำให้เบราว์เซอร์คำนวณตำแหน่งขององค์ประกอบทั้งหมดในหน้าใหม่ (reflow) ดังนั้นหลีกเลี่ยงการทำมากเกินไป ชำระเงินที่รายการนี้สำหรับประเภทของสิ่งที่เรียก reflow
Marcelo Lazaroni

คำตอบ:


1286

คุณควรใช้.offsetWidthและ.offsetHeightคุณสมบัติ .styleหมายเหตุพวกเขาอยู่กับองค์ประกอบที่ไม่

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

ฟังก์ชัน.getBoundingClientRect()ส่งคืนขนาดและตำแหน่งขององค์ประกอบเป็นตัวเลขทศนิยมหลังจากทำการแปลง 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,
}

174
ระวัง! offsetHeight / offsetWidth สามารถส่งคืน 0 ถ้าคุณทำการแก้ไข DOM บางอย่างกับองค์ประกอบเมื่อเร็ว ๆ นี้ คุณอาจต้องเรียกรหัสนี้ในการโทร setTimeout หลังจากที่คุณแก้ไของค์ประกอบ
Dan Fabulich

37
เอกสารเกี่ยวกับ.offsetWidthและ.offsetHeight: developer.mozilla.org/en/Determining_the_dimensions_of_elements
Denilson Sá Maia

30
ภายใต้สถานการณ์ใดที่ส่งคืน 0
Cheetah

46
@JDandChips: offsetWidthจะเป็น 0 หากองค์ประกอบนั้นdisplay:noneในขณะที่การคำนวณwidthอาจยังคงมีค่าบวกในอินสแตนซ์นี้ ไม่ได้ส่งผลกระทบต่อvisibility:hidden offsetWidth
MrWhite

21
@Supuhstar ทั้งคู่มีความหมายต่างกัน offsetWidthส่งคืนช่อง "ทั้ง" รวมถึงเนื้อหาการแพ็ดและเส้นขอบ ในขณะที่clientWidthส่งคืนขนาดของกล่องเนื้อหาเพียงอย่างเดียว (ดังนั้นมันจะมีค่าน้อยลงเมื่อใดก็ตามที่องค์ประกอบมีช่องว่างภายในที่ไม่ใช่ศูนย์และ / หรือเส้นขอบ) (แก้ไขแล้วเพื่อความชัดเจน)
Edurne Pascual

200

Element.getBoundingClientRect()ลองดูที่

วิธีการนี้จะกลับวัตถุที่มีwidth, heightและค่านิยมที่มีประโยชน์อื่น ๆ :

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

ตัวอย่างเช่น:

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

ฉันเชื่อว่านี่ไม่ได้มีปัญหาที่.offsetWidthและ.offsetHeightทำในสิ่งที่พวกเขากลับมาบางครั้ง0(ตามที่กล่าวไว้ในความคิดเห็นที่นี่ )

ความแตกต่างอีกอย่างคือgetBoundingClientRect()อาจส่งคืนพิกเซลเศษส่วนโดยที่.offsetWidthและ.offsetHeightจะปัดเศษเป็นจำนวนเต็มที่ใกล้เคียงที่สุด

IE8 หมายเหตุ : getBoundingClientRectไม่ส่งคืนความสูงและความกว้างในIE8และด้านล่าง *

หากคุณต้องรองรับ IE8 ให้ใช้.offsetWidthและ.offsetHeight:

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

มันน่าสังเกตว่า Object ที่ส่งคืนโดยวิธีนี้ไม่ใช่วัตถุปกติจริง ๆ คุณสมบัติของมันไม่สามารถนับได้ (ตัวอย่างเช่นObject.keysไม่สามารถใช้งานได้นอกกรอบ)

ข้อมูลเพิ่มเติมเกี่ยวกับสิ่งนี้ที่นี่: วิธีที่ดีที่สุดในการแปลง ClientRect / DomRect เป็นวัตถุธรรมดา

อ้างอิง:


8
getboundingClientRect () จะคืนค่าความกว้างและความสูงจริงขององค์ประกอบที่ปรับขนาดผ่าน css ในขณะที่offsetHeightและoffsetWidthจะไม่
ลุค

66

หมายเหตุ : คำตอบนี้ถูกเขียนขึ้นในปี 2008 ในขณะที่โซลูชันข้ามเบราว์เซอร์ที่ดีที่สุดสำหรับคนส่วนใหญ่คือการใช้ jQuery ฉันจะทิ้งคำตอบไว้สำหรับลูกหลานและถ้าคุณใช้ jQuery นี่เป็นวิธีที่ดีในการทำ หากคุณกำลังใช้เฟรมเวิร์กอื่นหรือ JavaScript ที่บริสุทธิ์คำตอบที่ยอมรับอาจเป็นหนทางไป

ในฐานะของ jQuery 1.2.6 คุณสามารถใช้หนึ่งของแกนฟังก์ชั่น CSS , heightและwidth(หรือouterHeightและouterWidthตามความเหมาะสม)

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

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

45

ในกรณีที่เป็นประโยชน์กับทุกคนฉันใส่กล่องข้อความปุ่มและ div ทั้งหมดด้วย 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>

ฉันลองมันด้วยโครเมี่ยม, Firefox และ ie-edge, ฉันลอง jquery และไม่, และฉันลองด้วยและไม่ใส่box-sizing:border-boxก็ได้ อยู่เสมอด้วย<!DOCTYPE html>

ผลลัพธ์ที่ได้:

                                                               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

1
เพื่อให้ชัดเจน ... เบราว์เซอร์ใด ๆ ที่ทำสิ่งที่แตกต่างจาก eachother? ฉันไม่สามารถพบความแตกต่างใด ๆ ... นอกจากนี้ผมลงไม่ได้ออกเสียงลงคะแนน (ยัง) แต่นี้ไม่ได้จริงๆตอบคำถามโดยตรงถึงแม้ว่ามันอาจจะ editted ได้อย่างง่ายดายจะทำเช่นนั้น
Zach Lysobey

1
ไม่ได้มุ่งที่จะตอบคำถาม - ได้รับคำตอบแล้ว เพียงแค่ข้อมูลที่เป็นประโยชน์และใช่เบราว์เซอร์เวอร์ชันหลักทั้งหมดจะเห็นด้วยกับค่าเหล่านี้ - ซึ่งเป็นสิ่งที่ดี
เกรแฮม

3
ถ้าคุณไม่ตั้งใจตอบคำถามนี่ก็ไม่ได้อยู่ที่นี่จริงๆ (เป็น "คำตอบ") ฉันจะลองใส่มันลงในแหล่งข้อมูลภายนอก (อาจเป็นส่วนสำคัญ GitHub หรือโพสต์บล็อก) และเชื่อมโยงมันในความคิดเห็นในคำถามเดิมหรือหนึ่งในคำตอบ
Zach Lysobey

21
@ZachLysobey มีข้อยกเว้นสำหรับทุกกฎ - และนี่คือสิ่งดีๆที่ควรรู้
Dan Nissenbaum

16

ตามMDN: การกำหนดขนาดขององค์ประกอบ

offsetWidthและoffsetHeightส่งคืน "จำนวนพื้นที่ทั้งหมดที่องค์ประกอบครอบครองรวมถึงความกว้างของเนื้อหาที่มองเห็นได้แถบเลื่อน (ถ้ามี) ช่องว่างภายในและขอบ"

clientWidthและclientHeightกลับมา "พื้นที่ที่เนื้อหาที่แสดงจริงใช้เวลารวมถึงการขยาย แต่ไม่รวมถึงเส้นขอบระยะขอบหรือแถบเลื่อน"

scrollWidthและscrollHeightส่งคืน "ขนาดที่แท้จริงของเนื้อหาโดยไม่คำนึงว่าจะปรากฏขนาดเท่าใด"

ดังนั้นขึ้นอยู่กับว่าเนื้อหาที่วัดได้นั้นคาดว่าจะออกนอกพื้นที่ที่สามารถดูได้ในปัจจุบัน


5

คุณจะต้องคำนวณมันสำหรับ IE7 และเก่ากว่า (และเฉพาะในกรณีที่เนื้อหาของคุณไม่มีขนาดคงที่) ฉันขอแนะนำให้ใช้ความคิดเห็นตามเงื่อนไข HTML เพื่อ จำกัด การแฮ็กกับ IE เก่าที่ไม่รองรับ CSS2 สำหรับเบราว์เซอร์อื่น ๆ ให้ใช้สิ่งนี้:

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

นี่คือทางออกที่สมบูรณ์แบบ มันเป็นศูนย์กลาง<div>ของทุกขนาดและหดห่อให้มีขนาดของเนื้อหา


3

มันง่ายที่จะแก้ไขรูปแบบองค์ประกอบ แต่ค่อนข้างยุ่งยากในการอ่านค่า

JavaScript ไม่สามารถอ่านคุณสมบัติสไตล์อิลิเมนต์ใด ๆ (elem.style) ที่มาจาก css (ภายใน / ภายนอก) เว้นแต่คุณจะใช้การเรียกเมธอดในตัว getComputedStyle ใน javascript

getComputedStyle (องค์ประกอบ [หลอก])

องค์ประกอบ:องค์ประกอบที่จะอ่านค่าสำหรับ
หลอก:องค์ประกอบหลอกหากจำเป็นเช่น :: ก่อน สตริงว่างหรือไม่มีอาร์กิวเมนต์หมายถึงองค์ประกอบเอง

ผลที่ได้คือวัตถุที่มีคุณสมบัติสไตล์เช่น elem.style แต่ตอนนี้เกี่ยวกับการเรียน CSS ทั้งหมด

ตัวอย่างเช่นสไตล์ที่นี่ไม่เห็นระยะขอบ:

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

ดังนั้นปรับเปลี่ยนรหัสจาวาสคริปต์ของคุณเพื่อรวม getComputedStyle ขององค์ประกอบที่คุณต้องการรับความกว้าง / ความสูงหรือคุณลักษณะอื่น ๆ

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

}

คำนวณและแก้ไขค่า

มีสองแนวคิดใน CSS:

ค่าลักษณะที่คำนวณได้คือค่าหลังจากใช้กฎ CSS ทั้งหมดและการสืบทอด CSS เป็นผลมาจากการเรียงซ้อน CSS มันดูเหมือนความสูง: 1em หรือขนาดตัวอักษร: 125%

ค่าสไตล์ที่ได้รับการแก้ไขคือค่าสุดท้ายที่ใช้กับองค์ประกอบ ค่าเช่น 1em หรือ 125% สัมพันธ์กัน เบราว์เซอร์ใช้ค่าที่คำนวณและทำให้ทุกหน่วยคงที่และแน่นอนเช่น: height: 20px หรือ font-size: 16px สำหรับคุณสมบัติทางเรขาคณิตที่ได้รับการแก้ไขอาจมีจุดลอยตัวเช่นความกว้าง: 50.5px

เมื่อนานมาแล้ว getComputedStyle ถูกสร้างขึ้นเพื่อรับค่าจากการคำนวณ แต่กลับกลายเป็นว่าค่าที่ได้รับการแก้ไขนั้นสะดวกกว่าและมาตรฐานเปลี่ยนไป
ดังนั้นทุกวันนี้ getComputedStyle จึงส่งกลับค่าที่แก้ไขแล้วของคุณสมบัติ

โปรดทราบ:

getComputedStyle ต้องการชื่อคุณสมบัติแบบเต็ม

คุณควรขอคุณสมบัติที่แน่นอนที่คุณต้องการเช่น paddingLeft หรือความสูงหรือความกว้างเสมอ มิฉะนั้นจะไม่รับประกันผลลัพธ์ที่ถูกต้อง

ตัวอย่างเช่นหากมีคุณสมบัติ paddingLeft / paddingTop แล้วเราควรได้รับ getComputedStyle (elem) .padding อย่างไร ไม่มีอะไรหรืออาจจะเป็น "สร้าง" คุณค่าจากการรู้จัก paddings? ไม่มีกฎมาตรฐานที่นี่

มีความไม่สอดคล้องกันอื่น ๆ ตัวอย่างเช่นเบราว์เซอร์บางตัว (Chrome) แสดง 10px ในเอกสารด้านล่างและเบราว์เซอร์บางตัว (Firefox) - อย่า:

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

สำหรับข้อมูลเพิ่มเติมhttps://javascript.info/styles-and-classes


1

element.offsetWidth และ element.offsetHeight ควรทำตามที่แนะนำในโพสต์ก่อนหน้า

อย่างไรก็ตามหากคุณต้องการจัดกึ่งกลางเนื้อหามีวิธีที่ดีกว่าในการทำเช่นนั้น สมมติว่าคุณใช้ xhtml DOCTYPE ที่เข้มงวด กำหนดระยะขอบ: 0, คุณสมบัติอัตโนมัติและความกว้างที่ต้องการใน px เป็นแท็ก body เนื้อหาจะถูกจัดกึ่งกลางให้ตรงกับหน้า


1
ผมคิดว่าเขาต้องการที่จะอยู่ตรงกลางในแนวตั้งมากเกินไปซึ่งเป็นความเจ็บปวดที่เหมาะสมกับ CSS ถ้าคุณไม่สามารถเป็นไปตามเกณฑ์บางอย่าง (เช่นเนื้อหาที่รู้จักกันขนาด)
เกร็ก

1

... ดูเหมือนว่า CSS ช่วยให้ div อยู่ตรงกลาง ...

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

0

นอกจากนี้คุณสามารถใช้รหัสนี้:

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

var h = divID.style.pixelHeight;

1
อืมทำงานได้ใน Chrome และ IE9 ดูเหมือนว่าจะไม่ทำงานใน Firefox ใช้งานได้กับเอกสารบางประเภทเท่านั้นหรือไม่
BrainSlugs83

1
pixelHeight เป็นสิ่งประดิษฐ์ของ Internet Explorer ที่ไม่ควรใช้อีกต่อไปstackoverflow.com/q/17405066/2194590
HolgerJeromin

0

หากคุณต้องการจัดกึ่งกลางในพอร์ตการแสดงผลของเบราว์เซอร์ คุณสามารถทำได้ด้วย CSS เท่านั้น

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

-2

นี่คือรหัสสำหรับWKWebViewสิ่งที่กำหนดความสูงขององค์ประกอบ Dom เฉพาะ (ทำงานไม่ถูกต้องสำหรับทั้งหน้า)

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 {

        }
    }
}

เพื่อให้ชัดเจนนี่คือswiftรหัสiOS ใช่มั้ย ไม่ใช่ JavaScript ฉันหยุดการโหวต (b / c นี้อาจมีประโยชน์จริง ๆ ) แต่โปรดทราบว่านี่ไม่ตอบคำถามและน่าจะเหมาะสมกว่าสำหรับคำถามอื่นที่เฉพาะเจาะจงกับ iOS หากไม่มีอยู่แล้วให้ลองพิจารณาถามตัวเองและตอบคำถามด้วยตนเอง
Zach Lysobey

-3

ถ้า offsetWidth ส่งคืน 0 คุณสามารถรับคุณสมบัติความกว้างขององค์ประกอบและค้นหาตัวเลข "100px" -> 100

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.