在以往我都是對這些屬性死記硬背,很少真正理解過,忘記了就查手冊。看完本文我相信這種情況就不會再發生了。
元素占據的物理空間的尺寸
如果你需要獲得元素占據的物理空間,那麼使用offsetHeight和offsetWidth。
自然而然此物理空間必然包含的有:padding、滾動條、border。這兩個屬性與getBoundingClientRect()的height和width屬性是一致的。
為了幫助理解請看下圖:
元素內容的可視區域的尺寸
可視區域包含padding,但是不包含border、滾動條。此時請使用clientHeight和clientWidth。
為了幫助理解請看下圖:
元素全部內容的尺寸
如果你要獲取元素內容的真正大小,當然也包含那些不可見的內容,此時你需要使用scrollHeight/scrollWidth。
例如一張600*400的圖片被包含在一個300*300的可滾動的容器元素內,那麼scrollWidth將返回600,而scrollHeight將返回400
實測:
當元素存在滾動條時,chrome浏覽器獲取元素的scrollHeight有時候不准確!但是本文的例子是正確的,不知道怎麼重現。
獲取元素的真實尺寸 大部分場景,我們並不關心元素的全部內容的尺寸(window/document/body元素除外),最常用的恐怕還是獲取元素占據的物理空間(offsetHeight/offsetWidth)。
比如對某段文字設置自定義的tooltip,這個時候需要獲取目標元素的高度然後對tooltip進行定位。
不論是clientHeight還是offsetHeight它們都包含了padding,假設這段文字包含了100px的padding,這個tooltip的位置顯然會極其的不准確。
因此獲取元素的高度通常是需要去掉padding。
由於元素的style屬性只能獲取到內聯樣式的width/height,所以在IE中需要使用el.currentStyle.height/width,
而標准浏覽器中使用window.getComputedStyle(el,null).width/height。
下面是我整理的園友Snandy的一個用戶獲取元素真實高度和寬度的方法 :
復制代碼 代碼如下:
function getStyle(el) {
if(window.getComputedStyle) {
return window.getComputedStyle(el, null);
}else{
return el.currentStyle;
}
}
function getWH(el, name) {
var val = name === "width" ? el.offsetWidth : el.offsetHeight,
which = name === "width" ? ['Left', 'Right'] : ['Top', 'Bottom'];
// display is none
if(val === 0) {
return 0;
}
var style = getStyle(el);
for(var i = 0, a; a = which[i++];) {
val -= parseFloat( style["border" + a + "Width"]) || 0;
val -= parseFloat( style["padding" + a ] ) || 0;
}
return val;
}
使用腳本庫往往能幫助我們解決一些棘手的問題,下面來看看jQuery的相關方法
jQuery.height()/jQuery.width()
返回一個整數,為匹配的jQuery對象集合中第一個元素的高度值。
注意此結果不關心盒式模型,不包含元素的padding。此方法等價於getWH(el,'height/width')
這個方法同樣能計算出window和document的高度。
jQuery.innerHeight()/jQuery.innerWidth()
對比jQuery.height() /jQuery.width() 此結果包含padding,但是不包含border。
當元素el未設置border時,此方法等價於el.offsetHeight/offsetWidth
jQuery.outerHeight()/jQuery.outerWidth()
對比jQuery.height() /jQuery.width() 此結果包含padding和border,默認不包含margin。
當元素未指定margin時,此方法等價於el.offsetHeight/offsetWidth
可以傳入一個bool變量來指定是否包含margin。
注意:
由於獲取普通元素的全部內容的尺寸意義不大(某些元素除外如window、document、iframe等),
所以jQuery的這三個方法都未包含不可見區域。
小測試
下面是一個div設置了高度200px,padding為3px,border為1px,裡面的圖片為958*512
上面的值你都猜對了嗎?
更新
又檢查了下測試代碼,scrollHeight在chrome下不准確的原因是使用了jQuery.ready(),而剛好測試的元素內部包含一張圖片。
用過jQuery.ready()的都知道,此時DOM樹已經加載完成,但是圖片元素還沒有完全加載, 因而chrome的處理方式是對的。
於是我就上例又測試了一遍:
在IE 6 / 8返回結果為522/519
chrome返回結果為189
Firefox有一點特殊,不斷刷新頁面會有兩種結果出現:1)522;2)189,但是大部分情況是522
出現這種情況肯定與jQuery 1.6.2的ready函數的實現有關系。
不過就上述結果來看,是否可以推斷jQuery.ready()在chrome中是最安全最快的。
[Ctrl+A 全選 注:如需引入外部Js需刷新才能執行]
參考資料
各情景下元素寬高的獲取 by Snandy
Determining the dimensions of elements
Measuring Element Dimension and Location with CSSOM in Internet Explorer 9