HTML中常見的各種位置距離(clientTop clientLeft clientWidth ClientHeight offsetleft offsettop offsetwidth offset
附上一個看不太懂的圖:
DOM中都有一些什麼寬度、高度。
常見的
offsetWidth |
clientWidth |
scrollWidth |
offsetHeight |
clientHeight |
scrollHeight |
offsetLeft |
clientLeft |
scrollLeft |
offsetTop |
clientTop |
scrollTop |
下面我們來一一講解
offsetleft:元素的邊框的外邊緣距離與已定位的父容器(offsetparent)的左邊距離(不包括元素的邊框和父容器的邊框)。
offsettop:同理是指元素的邊框的外邊緣距離與已定位的父容器(offsetparent)的上邊距離(不包括元素的邊框和父容器的邊框)。
offsetwidth:描述元素外尺寸寬度,是指 元素內容寬度+內邊距寬度(左右兩個)+邊框(左右兩個),不包括外邊距和滾動條部分。
offsetheight:同理 描述元素外尺寸高度,是指 元素內容高度+內邊距高度(上下兩個)+邊框(上下兩個),不包括外邊距和滾動條部分。
下面我們看一下一段程式碼
<div id="divParent" style="padding: 8px; background-color:#CCC; position: relative;"> <div id="divChild" style="background-color:#C00; margin: 30px; padding: 10px; height: 200px; width: 200px; border: solid 10px #0000CC;"> </div> </div>
<script type="text/javascript"> var div = document.getElementById(‘divChild‘); var offsetHeight = div.offsetHeight; var offsetWidth = div.offsetWidth; div.innerHTML += ‘offsetHeight: ‘ + offsetHeight + ‘<br />‘; div.innerHTML += ‘offsetWidth: ‘ + offsetWidth + ‘<br />‘; var offsetLeft = div.offsetLeft; var offsetTop = div.offsetTop; div.innerHTML += ‘offsetLeft: ‘ + offsetLeft + ‘<br />‘; div.innerHTML += ‘offsetTop: ‘ + offsetTop + ‘<br />‘; var offsetParent = div.offsetParent; div.innerHTML += ‘offsetParent: ‘ + offsetParent.id + ‘<br />‘; </script>
看一下效果
現在我們按照上面的說明比對一下
offsetleft:(div id=divChild)自己的margin 30(外邊距--距離父容器左邊30px)+ (div id=divParent) 父親的padding 8 (父容器的內邊左距離 8px)=38
offsettop:margin 30+ padding 8=38;
offsetwidth:本身的寬度(200)+內邊距左右(10*2)+邊框左右(10*2)=240; width+padding+border;
offsetheight:同理;
下面我們來看下第二組
clientleft:元素的內邊距的外邊緣和邊框的外邊緣的距離,實際就是邊框的左邊框寬度
clienttop:同理邊框的上邊框的寬度
clientwidth:用於描述元素內尺寸寬度,是指 元素內容+內邊距 大小,不包括邊框、外邊距、滾動條部分
clientheight:同理 用於描述元素內尺寸高度,是指 元素內容+內邊距 大小,不包括邊框、外邊距、滾動條部分
我們只更改一下JavaScript的程式碼,DOM不改變
chrome 41 版本
clientleft:左邊框寬度 10; // 相當於做左border的厚度
clienttop:10;
clientwidth:本身寬度(200)+內邊距(10*2)=220; // width+padding;
clientheight:本身高度(200)+內邊距(10*2)=220;
正確,下面我們來看下巢狀的div盒子模型圖
div id=divChild
div id=divParent
符合我們上面所說的,下面我們看下
scrollwidth:內容區域尺寸加上內邊距加上溢位尺寸,當內容正好和內容區域匹配沒有溢位時,這些屬性與clientWidth和clientHeight相等
scrollheight:同上
scrolltop:滾動條上方捲去的高度
scrollleft:滾動條左邊捲去的寬度
好現在我們 看一段程式碼
<div id="divParent" style="padding: 8px; background-color: #aaa; height:200px; width:300px; overflow:auto" >
<div id="divChild" style="background-color: #0f0;height: 400px; width: 500px; border: solid 10px #f00;">
</div>
</div>
<script type="text/javascript">
var divParent= document.getElementById("divParent");
var scrollwidth = divParent.scrollWidth;
var scrollheight = divParent.scrollHeight;
var scrolltop = divParent.scrollTop;
var scrollleft = divParent.scrollLeft;
divChild.innerHTML += ‘clientWidth: ‘ + scrollwidth + ‘<br />‘;
divChild.innerHTML += ‘clientHeight: ‘ + scrollheight + ‘<br />‘;
</script>
現在我們要計算id=divParent的scrollheight,和scrollwidth。根據上面的說明,我們知道應該按照下面的公式計算
scrollwidth=子div的寬度(500)+子div的邊框(10*2)+父容器的padding(8)=528
scrollheight=子div的高度(400)+子div的邊框(10*2)+父容器的padding(8)=428
現在我們驗證一下
我們發現在 ie8及之後的 瀏覽器 為428,firework 也為428;而 chrome Safari opera 都為436;
因此我們可以猜測 chrome和 Safari、opera 在計算 scrollheight時,加上了 父容器的下 padding(8) 即 428+8=436;
下面我們在看看scrolltop和scrollleft的值怎麼樣
測試了好幾個瀏覽器都發現其值為零,這是腫麼回事,尼瑪,萬能的百度、谷歌,原來我的滾動條一直在頂端和左端,沒有捲走高度,我們修改一下程式碼,將顯示內容繫結到onscroll事件
<script type="text/javascript">
var divParent = document.getElementById("divParent");
divParent.onscroll = function () {
divChild.innerHTML = "";
var scrollwidth = divParent.scrollWidth;
var scrollheight = divParent.scrollHeight;
var scrolltop = divParent.scrollTop;
var scrollleft = divParent.scrollLeft;
divChild.innerHTML += ‘clientWidth: ‘ + scrollwidth + ‘<br />‘;
divChild.innerHTML += ‘clientHeight: ‘ + scrollheight + ‘<br />‘;
divChild.innerHTML += ‘scrolltop: ‘ + scrolltop + ‘<br />‘;
divChild.innerHTML += ‘scrollleft: ‘ + scrollleft + ‘<br />‘;
}
</script>
終於發現值改變了
另外我們在使用window的pageXOffset,pageYOffset求瀏覽器滾動條的捲去的高度和左邊的距離,同時scrolltop、scrollleft也可以,但是要注意
當我們網頁頁面申明瞭dtd(文件模型時), 使用document.documentElement.scrolltop scrollleft獲取瀏覽器捲去上面的距離,左邊捲去的距離。
如果網頁沒有申明dtd(怪異模式時),使用document.body.scrolltop scrollleft獲取上邊捲去的距離、左邊捲去的距離。
什麼是dtd,這裡簡單解釋一下,我們使用vs新建頁面時,在每個網頁的頂端 一般會有這樣的申明
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
這裡申明瞭 網頁的模型 ,再瀏覽器載入網頁時,會選擇對應的模式渲染網頁。
現在我們來測試一下
<div id="divParent" style="padding: 8px; background-color: #aaa; height:1200px; width:300px; overflow:auto" >
<div id="divChild" style="background-color: #0f0;height: 400px; width: 500px; border: solid 10px #f00; position:absolute">
</div>
</div>
<script type="text/javascript">
var divParent = document.getElementsByTagName("body")[0];
divParent.onscroll = function () {
divChild.innerHTML = "";
divChild.style.top = window.pageYOffset + "px";
var scrollwidth = divParent.scrollWidth;
var scrollheight = divParent.scrollHeight;
var scrolltop = divParent.scrollTop;
var scrollleft = divParent.scrollLeft;
var pagexoffset = window.pageXOffset;
var pageyoffset = window.pageYOffset;
var documentelementtop = document.documentElement.scrollTop;
var documentelementleft = document.documentElement.scrollLeft;
var bodyscrolltop = document.body.scrollTop;
var bodyscrollleft = document.body.scrollLeft;
divChild.innerHTML += ‘clientWidth: ‘ + scrollwidth + ‘<br />‘;
divChild.innerHTML += ‘clientHeight: ‘ + scrollheight + ‘<br />‘;
divChild.innerHTML += ‘scrolltop: ‘ + scrolltop + ‘<br />‘;
divChild.innerHTML += ‘scrollleft: ‘ + scrollleft + ‘<br />‘;
divChild.innerHTML += ‘pagexoffset: ‘ + pagexoffset + ‘<br />‘;
divChild.innerHTML += ‘pageyoffset: ‘ + pageyoffset + ‘<br />‘;
divChild.innerHTML += ‘documentelementtop: ‘ + documentelementtop + ‘<br />‘;
divChild.innerHTML += ‘documentelementleft: ‘ + documentelementleft + ‘<br />‘;
divChild.innerHTML += ‘bodyscrolltop: ‘ + bodyscrolltop + ‘<br />‘;
divChild.innerHTML += ‘bodyscrollleft: ‘ + bodyscrollleft + ‘<br />‘;
}
</script>
chrome測試結果,我們發現 pagexoffset document.body.scrolltop 可以用,但是注意 我當前的申明瞭 html5的<!DOCTYPE html>,說明document.documentelement可以用的。
在來看看 firefox的測試效果,同樣申明瞭文件型別 這裡 document.documentelement可以用,尼瑪真是日了狗了,難道是html5 文件型別特殊一點,我們測試一下其他型別的文件型別
但是發現結果和上面的一樣,好吧,不管上面那些了,下面總結如何相容scrolltop如果是求 scrolltop 可以取 body.scrolltop 和documen.documentelement.scrolltop的max值,這樣不管如何總能取一個正確的值。
我們在上面的章節知道了如何取scrolltop值,接下來我們就來介紹一下dom中的視窗座標和文件座標,
視窗座標:當前顯示可見的頁面的左上角的座標(如果出現滾動條,且滾動條發生滾動,則 視窗座標和文件座標不一致,因為視窗座標只顯示當前顯示的頁面的部分,而文件可能因為滾動條的緣故遮蓋了);
文件座標:垂直滾動條在最上方,沒有滾動,水平滾動條在最左邊,沒有滾動時,時的左上方的座標
如果沒有滾動條時,視窗座標和文件座標一致。
那如何在視窗座標和文件座標之間進行轉換呢,這裡我們就要用到上面的滾動條捲去的高度和座標的距離,假設,有一個元素在文件中的y座標(即垂直方向的)是200px;但是我們通過滾動條向下滾動了75px,那麼當前的視窗座標就為125px;
因此如果scrolltop的值大於0的話 我們視窗的座標y=文件的座標y-scrolltop,
同時視口座標也有對應的方法可以使用
可以通過呼叫元素的getBoundingClientRect方法。方法返回一個有left、right、top、bottom屬性的物件,分別表示元素四個位置的相對於視口的座標。getBoundingClientRect所返回的座標包含元素的內邊距和邊框,不包含外邊距。相容性很好,非常好用。
下面貼一段犀牛角上的程式碼
得到滾動條值
function getScrollOffsets(w) { var w = w || window;
//除ie8及更早版本,其他瀏覽器都能使用 if (w.pageXoffset != null) { return { x: w.pageXoffset, y: pageYoffset }; }
//標註模式ie(或任何瀏覽器) var d = w.document; if (document.compatMode == "CSS1Compat") return { x: d.documentElement.scrollLeft, y: d.documentElement.scrollTop };
//怪異模式下(沒有申明dtd) return { x: d.body.scrollLeft, y: d.body.scrollTop }; }
通過使用這個函式發現也不是很相容 在chrome中一直是0,說明即使在標準模型中,,即申明瞭dtd chrome 也不能取documentElement.scrollLeft值。opera也同樣不能取值,firefox能取值。因此早平常的使用中我還是 使用math.max(docuemnt.body.scrolltop,docuemnt.documentelement.scrolltop)來使用。