Làm cách nào để truy xuất chiều rộng và chiều cao thực tế của phần tử HTML?


893

Giả sử rằng tôi có một <div>cái mà tôi muốn tập trung vào màn hình của trình duyệt (khung nhìn). Để làm như vậy, tôi cần tính chiều rộng và chiều cao của <div>phần tử.

Tôi nên dùng gì? Vui lòng bao gồm thông tin về khả năng tương thích trình duyệt.


9
Hãy nhớ rằng việc lấy chiều cao của một phần tử thông qua bất kỳ phương thức nào luôn có tác động đến hiệu suất vì nó làm cho trình duyệt tính toán lại vị trí của tất cả các phần tử trong trang (chỉnh lại dòng). Do đó, tránh làm điều đó quá nhiều. Kiểm tra danh sách này cho những thứ gì kích hoạt một dòng lại.
Marcelo Lazaroni

Câu trả lời:


1286

Bạn nên sử dụng .offsetWidth.offsetHeightcác thuộc tính. Lưu ý họ thuộc về yếu tố, không .style.

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

Hàm.getBoundingClientRect() trả về kích thước và vị trí của phần tử dưới dạng số dấu phẩy động sau khi thực hiện các phép biến đổi 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
Coi chừng! offsetHeight / offsetWidth có thể trả về 0 nếu bạn đã thực hiện một số sửa đổi DOM cho thành phần gần đây. Bạn có thể phải gọi mã này trong cuộc gọi setTimeout sau khi bạn đã sửa đổi thành phần.
Dan Fabulich

37
Tài liệu về .offsetWidth.offsetHeight: developer.mozilla.org/en/Determining_the_dimensions_of_elements
Denilson Sá Maia

30
Trong trường hợp nào nó trả về 0?
Cheetah

46
@JDandChips: offsetWidthsẽ là 0 nếu phần tử là display:none, trong khi phần tử được tính toán widthvẫn có thể có giá trị dương trong trường hợp này. visibility:hiddenkhông ảnh hưởng đến offsetWidth.
MrWhite

21
@Supuhstar đều có ý nghĩa khác nhau. offsetWidthtrả về hộp "toàn bộ" bao gồm nội dung, phần đệm và đường viền; trong khi clientWidthtrả về kích thước của hộp nội dung một mình (vì vậy nó sẽ có giá trị nhỏ hơn bất cứ khi nào phần tử có bất kỳ phần đệm và / hoặc đường viền khác không). (mod được chỉnh sửa cho rõ ràng)
Edurne Pascual

200

Hãy nhìn vào Element.getBoundingClientRect().

Phương pháp này sẽ trả về một đối tượng chứa width, heightvà một số giá trị hữu ích khác:

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

Ví dụ:

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

Tôi tin rằng điều này không có vấn đề .offsetWidth.offsetHeightđôi khi họ quay trở lại 0(như được thảo luận trong các ý kiến ​​ở đây )

Một sự khác biệt khác là getBoundingClientRect()có thể trả về các pixel phân đoạn, trong đó .offsetWidth.offsetHeightsẽ làm tròn đến số nguyên gần nhất.

Lưu ý IE8 : getBoundingClientRectkhông trả về chiều cao và chiều rộng trên IE8 trở xuống. *

Nếu bạn phải hỗ trợ IE8, hãy sử dụng .offsetWidth.offsetHeight:

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

Cần lưu ý rằng đối tượng được trả về bởi phương thức này không thực sự là một đối tượng bình thường . Các thuộc tính của nó không thể đếm được (vì vậy, ví dụ, Object.keyskhông hoạt động ngoài luồng.)

Thông tin thêm về điều này tại đây: Cách tốt nhất để chuyển đổi ClientRect / DomRect thành Đối tượng đơn giản

Tài liệu tham khảo:


8
getboundingClientRect () sẽ trả về chiều rộng và chiều cao thực tế của các phần tử được chia tỷ lệ qua css trong khi đó offsetHeightoffsetWidthsẽ không.
Luke

66

LƯU Ý : câu trả lời này được viết vào năm 2008. Tại thời điểm đó, giải pháp đa trình duyệt tốt nhất cho hầu hết mọi người thực sự là sử dụng jQuery. Tôi sẽ để lại câu trả lời cho hậu thế và, nếu bạn đang sử dụng jQuery, đây là một cách tốt để làm điều đó. Nếu bạn đang sử dụng một số khung công tác hoặc JavaScript thuần túy khác, câu trả lời được chấp nhận có lẽ là cách tốt nhất.

Tính đến jQuery 1.2.6 bạn có thể sử dụng một trong các lõi chức năng CSS , heightwidth(hoặc outerHeightouterWidth, nếu thích hợp).

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

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

45

Chỉ trong trường hợp nó hữu ích với bất kỳ ai, tôi đặt một hộp văn bản, nút và div tất cả với cùng một 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>

Tôi đã thử nó trong chrome, firefox và eg-edge, tôi đã thử với jquery và không có, và tôi đã thử nó với và không box-sizing:border-box. Luôn luôn với<!DOCTYPE html>

Kết quả:

                                                               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
Để rõ ràng ... có bất kỳ trình duyệt nào làm bất cứ điều gì khác biệt với nhau không? Tôi không thể tìm thấy bất kỳ sự khác biệt nào ... Ngoài ra, tôi không bỏ phiếu (nhưng), nhưng điều này không thực sự trả lời trực tiếp câu hỏi, mặc dù nó có thể dễ dàng được chỉnh sửa để làm như vậy.
Zach Lysobey 11/03/2016

1
Không nhằm mục đích trả lời câu hỏi - nó đã được trả lời. Chỉ cần một số thông tin hữu ích và có tất cả các trình duyệt phiên bản mới nhất chính đồng ý với các giá trị này - đó là một điều tốt.
Graham

3
Chà ... nếu ý định của bạn không phải là trả lời câu hỏi, thì điều này thực sự không thuộc về nơi này (như một "câu trả lời"). Tôi sẽ xem xét đưa tài liệu này vào một số tài nguyên bên ngoài (có thể là ý chính của GitHub hoặc bài đăng trên blog) và liên kết nó trong một nhận xét về Câu hỏi ban đầu hoặc một trong những câu trả lời.
Zach Lysobey 14/03/2016

21
@ZachLysobey Có ngoại lệ cho mọi quy tắc - và đây là một điều thú vị, hữu ích để xem.
Dan Nissenbaum

16

Theo MDN: Xác định kích thước của các yếu tố

offsetWidthoffsetHeighttrả về "tổng dung lượng mà một phần tử chiếm, bao gồm chiều rộng của nội dung hiển thị, thanh cuộn (nếu có), phần đệm và đường viền"

clientWidthclientHeighttrả về "nội dung hiển thị thực tế chiếm bao nhiêu dung lượng, bao gồm phần đệm nhưng không bao gồm viền, lề hoặc thanh cuộn"

scrollWidthscrollHeighttrả về "kích thước thực tế của nội dung, bất kể số lượng hiện tại của nó là bao nhiêu"

Vì vậy, nó phụ thuộc vào việc nội dung đo được dự kiến ​​sẽ ra khỏi khu vực có thể xem hiện tại.


5

Bạn chỉ cần tính toán cho IE7 trở lên (và chỉ khi nội dung của bạn không có kích thước cố định). Tôi khuyên bạn nên sử dụng các nhận xét có điều kiện HTML để hạn chế hack đối với các IE cũ không hỗ trợ CSS2. Đối với tất cả các trình duyệt khác sử dụng điều này:

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

Đây là giải pháp hoàn hảo. Nó tập trung <div>vào bất kỳ kích thước nào, và thu nhỏ nó theo kích thước của nội dung của nó.


3

Thật dễ dàng để sửa đổi các kiểu phần tử nhưng hơi khó đọc giá trị.

JavaScript không thể đọc bất kỳ thuộc tính kiểu phần tử nào (elem.style) đến từ css (bên trong / bên ngoài) trừ khi bạn sử dụng lệnh gọi phương thức tích hợp getComputingStyle trong javascript.

getComputingStyle (phần tử [, giả])

Phần tử: Phần tử để đọc giá trị cho.
giả: Một phần tử giả nếu được yêu cầu, ví dụ :: trước. Một chuỗi rỗng hoặc không có đối số có nghĩa là chính phần tử.

Kết quả là một đối tượng có thuộc tính kiểu, như elem.style, nhưng bây giờ đối với tất cả các lớp css.

Chẳng hạn, ở đây phong cách không thấy lề:

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

Vì vậy, đã sửa đổi mã javaScript của bạn để bao gồm getComputingStyle của phần tử bạn muốn lấy chiều rộng / chiều cao hoặc thuộc tính khác

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

}

Giá trị được tính toán và giải quyết

Có hai khái niệm trong CSS:

Giá trị kiểu được tính là giá trị sau khi tất cả các quy tắc CSS và kế thừa CSS được áp dụng, là kết quả của bậc thang CSS. Nó có thể trông giống như chiều cao: 1em hoặc cỡ chữ: 125%.

Giá trị kiểu được giải quyết là giá trị cuối cùng được áp dụng cho phần tử. Các giá trị như 1em hoặc 125% là tương đối. Trình duyệt lấy giá trị được tính toán và làm cho tất cả các đơn vị cố định và tuyệt đối, ví dụ: height: 20px hoặc font-size: 16px. Đối với các thuộc tính hình học, các giá trị được phân giải có thể có một dấu phẩy động, như chiều rộng: 50,5px.

Cách đây rất lâu getComputingStyle đã được tạo để lấy các giá trị được tính toán, nhưng hóa ra các giá trị được giải quyết thuận tiện hơn nhiều và tiêu chuẩn đã thay đổi.
Vì vậy, ngày nay getComputingStyle thực sự trả về giá trị đã giải quyết của thuộc tính.

Xin lưu ý:

getComputingStyle yêu cầu tên thuộc tính đầy đủ

Bạn phải luôn luôn yêu cầu thuộc tính chính xác mà bạn muốn, như paddingLeft hoặc chiều cao hoặc chiều rộng. Nếu không, kết quả chính xác không được đảm bảo.

Chẳng hạn, nếu có thuộc tính paddingLeft / paddingTop, thì chúng ta nên lấy gì cho getComputingStyle (elem) .padding? Không có gì, hoặc có thể là một giá trị được tạo ra từ các bộ đệm đã biết? Không có quy tắc chuẩn ở đây.

Có những mâu thuẫn khác. Ví dụ: một số trình duyệt (Chrome) hiển thị 10px trong tài liệu bên dưới và một số trình duyệt (Firefox) - không:

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

để biết thêm thông tin https://javascript.info/styles-and-groupes


1

Element.offsetWidth và Element.offsetHeight nên làm, như được đề xuất trong bài viết trước.

Tuy nhiên, nếu bạn chỉ muốn tập trung vào nội dung, có một cách tốt hơn để làm như vậy. Giả sử bạn sử dụng DOCTYPE nghiêm ngặt xhtml. đặt lề: 0, thuộc tính tự động và chiều rộng yêu cầu tính bằng px cho thẻ body. Các nội dung được trung tâm liên kết với trang.


1
Tôi nghĩ rằng anh ấy cũng muốn tập trung vào nó theo chiều dọc, đó là một nỗi đau đúng với CSS trừ khi bạn có thể đáp ứng một số tiêu chí cụ thể (ví dụ: nội dung có kích thước đã biết)
Greg

1

... có vẻ như CSS giúp đặt div vào trung tâm ...

<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

bạn cũng có thể sử dụng mã này:

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

var h = divID.style.pixelHeight;

1
Hmm, hoạt động trong Chrome và IE9, dường như không hoạt động trong Firefox. Nó chỉ hoạt động cho các loại tài liệu nhất định?
BrainSlugs83

1
pixelHeight là một phát minh Internet Explorer không nên được sử dụng nữa stackoverflow.com/q/17405066/2194590
HolgerJeromin

0

nếu bạn cần căn giữa nó trong cổng hiển thị của trình duyệt; bạn chỉ có thể đạt được nó với CSS

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

-2

Đây là mã cho WKWebView xác định chiều cao của phần tử Dom cụ thể (không hoạt động đúng cho toàn bộ trang)

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 {

        }
    }
}

chỉ cần rõ ràng, đây là swiftmã iOS , phải không? Không phải JavaScript. Tôi đang từ chối một downvote (b / c điều này thực sự có thể khá hữu ích) nhưng xin lưu ý rằng điều này không trả lời câu hỏi và có thể sẽ phù hợp hơn với câu hỏi khác, cụ thể về iOS. Nếu chưa có, có lẽ nên xem xét một câu hỏi và tự trả lời.
Zach Lysobey

-3

Nếu offsetWidth trả về 0, bạn có thể lấy thuộc tính độ rộng kiểu của phần tử và tìm kiếm số đó. "100px" -> 100

/\d*/.exec(MyEuity.style. thong)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.