1. 程式人生 > >HTML中常見的各種位置距離(clientTop clientLeft clientWidth ClientHeight offsetleft offsettop offsetwidth offset

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)來使用。