不同瀏覽器獲取DOM元素的各種高度
一:介紹
不止一次被HTML中各種高度和寬度搞暈了,搞的每次做專案時都要去查相關的資料。趁著有時間好好把這塊的資料整理一下,以被以後使用。
下面是一張W3C中Window物件屬性圖。從圖中我們可以看到有關高度和寬度的幾個屬性,他們分別是innerHeight,innerWidth,outerHeight,outerWidth, pageXOffset,pageYOffset,screenLeft,screenTop,screenX,screenY。下面我們一個個來驗證他們各代表什麼。
二:innerHeight、innerWidth、outerHeight、outerWidth
innerHeight,innerWidth:返回視窗的文件顯示區的高度和寬度(不包括選單欄、工具欄以及滾動條的高度)。IE不支援這些屬性,它用document.documentElement(html元素)或者document.body(與IE版本有關)的clientWidth和clientHeight代替。在各個瀏覽器測試效果如下:
- 谷歌
- IE9+
- IE8
- IE7
- IE5
- FF
檢視上圖可知除了IE9以下不支援innerHeight屬性,其餘版本瀏覽器均支援。只是在不同的瀏覽器中有稍許區別。所有的瀏覽器均支援document.documentElement.clientHeight與document.body.clientHeight屬性。只不過在IE5中document.documentElement.clientHeight為0。所以要相容所有瀏覽器獲取文件顯示區高度和寬度可用以下程式碼。
lyq.getClientHeight = function(){ var clientHeight = Math.max(document.body.clientHeight, document.documentElement.clientHeight); return clientHeight; }
outerHeight,outerWidth:返回視窗的外部高度和高度。IE9以下不支援該屬性,其餘瀏覽器支援該屬性。但是在谷歌瀏覽器中outerHeight與innerHeight、outerWidth與 outerWidth返回相同的值即視窗的文件顯示區的高度和寬度,而非瀏覽器視窗的大小。但是在其它瀏覽器中如FF,Safari返回瀏覽器視窗本身的尺寸。
screenLeft,screenTop,screenX,screenY:聲明瞭視窗的左上角在螢幕上的的 x 座標和 y 座標。
screenLeft,screenTop在不同瀏覽器下的測試。
- 谷歌
- IE
- FF
- UC
經過觀察可以發現screenTop,screenLeft除了在火狐上不支援以外,在其它瀏覽器上均支援。只不過在IE和QQ瀏覽器上是計算文件顯示區距離螢幕的座標,而谷歌,UC是計算整個瀏覽器距離螢幕的座標(包含選單欄,工具欄等)。具體情況還要視瀏覽器定。
clientWidth = height + padding-left + padding-right - scrollbar.width(對大部分瀏覽器) clientHeight = 同clientWidth clientTop = border-top clientLeft = border-left 橫向滑動條的高度 = height + padding-top + padding-bottom - clientHeight 橫向滑動條的寬度 = width + padding-left + padding-right 垂直滑動條的高度 = height + padding-top + padding-bottom 垂直滑動條的寬度 = width + padding-left + padding-right - clientWidth offsetHeight:對於IE6,IE7,IE8以及最新的FF,谷歌,在元素上都是clientHeight + 滾動條高度 + 邊框 offsetWidth:同offsetHeight。 offsetTop = margin-top + top(相對於父視窗) offsetLeft = margin-left + left(相對於父視窗) scrollHeight = padding-top + padding-bottom + 內容margix box的高度。這個與滾動條無關,是內容的實際高度。 scrollWidth = 同scrollHeight。 在瀏覽器中的區別在於: IE6,IE7認為scrollHeight是網頁內容的實際高度,可以小於clientHeight。 FF,Chrome認為scrollHeight是網頁內容高度,最小值是clientHeight。 注:以上都是對一般元素而言,body和documentElement的clientHeight,offsetHeight和scrollHeight在各個瀏覽器中的計算方式又不同。在所有的瀏覽器中,如果你想獲取整個視窗的高度,你要用documentElement.clientHeight, 因為body.clientHeight是由它的內容決定的。 FF19 在body上設定overflow:scroll就是設定瀏覽器的滾動條,導致body.clientHeight永遠等於body.scrollHeight。 body clientHeight = body.padding + body.height(css設定或內容撐的) offsetHeight = clientHeight + body.border scrollHeight == clientHeight; documentElement clientHeight = window視窗高度 - scrollbar.height offsetHeight = body.offsetHeight + body.margin; scrollHeight >= clientHeight 元素上 offsetHeight = padding + border + height clientHeight = padding + height - scrollbar.height scrollHeight >= clientHeight 結果分析:FF認為scrollHeight的最小高度是clientHeight Chrome body clientHeight = body.padding + body.height(css設定或內容撐的) offsetHeight = body.clientHeight + bodt.border scrollHeight = body.padding + 內容的高度(與height樣式無關) 最小值為clientHeight documentElement clientHeight = window視窗高度 - 滾動條高度 offsetHeight = body.offsetHeight + body.margin scrollHeight = 內容的高度(與body上的height無關) 元素上 offsetHeight = padding + border + height clientHeight = padding + height - scrollbar.height scrollHeight >= clientHeight Safari5 body clientHeight = body.padding + body.height(CSS或內容撐的); offsetHeight = body.clientHeight + border; scrollHeight = body.padding + 內容的高度(與height樣式無關),但最小值是documentElement.clientHeight。 documentElement clientHeight = window視窗大小 – 滾動條大小 offsetHeight = body.offsetHeight + body.margin scrollHeight= 內容的高度(與body上的height無關),但最小值是documentElement.offsetHeight。 IE8 在IE8下,滾動條的大小是17個畫素。 body clientHeight= body.padding + body.height(css設定或內容撐大) offsetHeight = body.clientHeight + body.border scrollHeight = 內容的高度(與body上的height無關),但最小值是clientHeight。 documentElement clientHeight = 視窗大小(除去滾動條後) offsetHeight = clientHeight + 滾動條大小 + body.border scrollHeight= 內容的高度(與body上的height無關),但最小值是body.offsetHeight+ margin。 元素上 offsetHeight = padding + border + height。 clientHeight = padding + height - scrollbar.width。 scrollHeight >= clientHeight 從結果分析IE8認為scrollHeight>=clientHeight。 offsetLeft = 元素border左上角到畫布原點的距離 或 到offsetParent的borderbox頂部的距離。 IE7 在IE7中,body上設定的滾動條並不是視窗的滾動條,這個需要注意。 body clientHeight= body.padding + height(css設定或內容撐大)– body上的滾動條。 offsetHeight= clientHeight + 滾動條的大小+body.border。 scrollHeight= 內容的高度(與body上的height無關)。 documentElement clientHeight = window視窗大小(與滾動條的有無無關) offsetHeight = clientHeight。 scrollHeight = body.offsetHeight + border.margin 元素 offsetHeight = padding + border + height。 clientHeight = padding + height - scrollbar.width。 scrollHeight = padding + 內容margin box的高度 從結果分析,IE7認為scrollHeight可以小於clientHeight。 offsetLeft = 元素border box左上角到父容器(不是offsetParent)的borderbox左上角的距離。 IE6 在IE6中,與IE7類似, body上設定的滾動條並不是視窗的滾動條。 body clientHeight = body.padding + body.height offsetHeight = body.clientHeight + body.border + body上滾動條大小。 scrollHeight =內容的高度(與body上的height無關)。 documentElement 在IE6中,與IE7類似,雖然body上設定的滾動條並不是視窗的滾動條,但它的clientHeight和offsetHeight還算與其它瀏覽器想統一。 clientHeight = 視窗大小(除去視窗滾動條大小後) offsetHeight =clientHeight + body.border scrollHeight = body.offsetHeight + body.margin 元素 offsetHeight = padding + border + height。 clientHeight = padding + height - scrollbar.width。 scrollHeight = padding + 內容margin box的高度 從結果分析,IE6認為scrollHeight可以小於clientHeight。 scrollLeft:設定或獲取位於物件左邊界和視窗中目前可見內容的最左端之間的距離 scrollTop:設定或獲取位於物件最頂端和視窗中可見內容的最頂端之間的距離 Event物件屬性 clientX:相對於可視區域的x座標。 clientY:相對於可視區域的y座標。 screenX:相對於使用者螢幕x座標。 screenY:相對於使用者螢幕的y座標。 IE特有屬性 offsetX:滑鼠相對於目標事件的父元素的內邊界在x座標的位置 offsetY:滑鼠相對於目標事件的父元素的內邊界在y座標的位置 x:設定或獲取滑鼠指標位置相對於父文件的y座標。同clientX y:設定或獲取滑鼠指標位置相對於父文件的y座標。同clientY 說明:event.clientX返回事件發生時,mouse相對於客戶視窗的x座標,event.X也一樣。但是如果設定事件物件的定位屬性值為relative,event.clientX不變,而event.x返回事件物件的相對於本體的座標。火狐下用pageX,pageY代替x與y屬性。
說了這麼多,我們來看看jQuery中是如何處理這些差異的(jQuery中的event物件重新封裝了)
offset():獲取匹配元素在當前視口的相對偏移,返回的物件包含兩個整型屬性:top和left。只對可見元素有效。 offsetParent():返回最近的定位祖先元素。 position():獲取匹配元素相對父元素的偏移,返回的物件包含兩個整型屬性:top和left。 scrollTop():獲取匹配位置相對滾動條頂部的偏移,此方法對可見和隱藏元素均有效。同JS中scrollTop。 scrollLeft():獲取匹配位置相對滾動條左側的偏移,此方法對可見和隱藏元素均有效。同JS中scrollLeft。 event.pageX:滑鼠相對於文件的左邊緣的位置。 event.pageY:滑鼠相對於文件的上邊緣的位置。 innerHeight():獲取匹配元素內部區域的高度(含padding,不含border) innerWidth():同innerHeight(); outerHeight(options):預設為false,包含padding和邊框;為true,margin也計算在內。 outerWidth(options):同outerHeight(options)。 height():返回內容高度,不含padding。 width():同height(); css("height"):返回的數值帶有"px"。而height()則沒有。 css("width"):返回的數值帶有"px"。而width()則沒有。 說明:height()總是返回內容寬度,不管CSS box-sizing 屬性值。height('value')設定的容器寬度是根據CSS box-sizing 屬性來定的,將這個屬性值改成border-box,將造成這個函式改變這個容器的outerHeight(false),而不是原來的內容高度。