DOM之parentNode與offsetParent


      DOM中有兩個屬性parentNode和offsetParent,想必區別大家都是知道的,可用法上還是有一些需要注意的地方,尤其是后者,想知道嗎?繼續往下看咯。

      parentNode指的是父節點,element.parentNode,獲取某一個元素的父節點,這里的父節點呢,只有一個,就是指的是最臨近的直接父節點。比如我們經常會有這樣的需求:一個列表,點擊刪除刪除一列,如下:

<ul id="list">
   <li>我是沐晴<span>刪除</span></li>
   <li>我是沐晴<span>刪除</span></li>
   <li>我是沐晴<span>刪除</span></li>
</ul>
var oList = document.getElementById("list");
var aSpan = oList.getElementsByTagName("span");
for(var i=0;i<aSpan.length;i++){ 
    aSpan[i].onclick = function(){ 
        this.parentNode.style.display = "none";
    }
}

例子很簡單,點擊讓對應的父元素隱藏即可。來看下一個屬性.

offsetParent 這里的父節點,指的是相對於父節點,也就是說某個元素相對於誰定位,誰就是他的父親。

和它很相似的屬性還有offsetLeft \ offsetTop ,他們指的是前元素到offsetParent的距離。

不過不同的瀏覽器對於這個屬性的解釋也是有一些不同的:什么時候元素會相對於別人定位呢,其實也就是有父元素設置相對定位,絕對定位的時候(relative,absolute),這個父元素就叫做定位父級,這個大家應該都懂。

其他瀏覽器下:

當沒有定位父級的時候: offsetParent 指的是body

有定位父級的時候:offsetParent 指的就是定位父級

IE7以下:

當沒有定位父級的時候又分兩種情況:

     如果自己沒有定位: offsetParent 指的是body

     如果自己有定位:offsetLeft 指的是 html

如果有定位父級:

     如果自己沒有定位: offsetParent 指的是body

 

     如果自己有定位:offsetLeft 指的是 定位父級

ie7以下,如果當前元素的某個父級觸發了layout,那么offsetParent就會被指向到這個觸發了layout特性的父節點上

所以我們在寫代碼的時候是需要注意這些細節的,我們在寫代碼的時候經常有這樣的需求,獲取一個元素到瀏覽器的距離,一般情況我們是會用到offsetLeft \ offsetTop ,但是這只適用於頁面沒有定位父級的時候,當我們的代碼很多的時候,其中有些元素可能被設置了定位的時候,這個值很可能就不准了。那么如何能完全准確的獲取到元素到文檔的距離呢?

  下面來看張圖:

求diiv1到文檔的距離,灰色的框是文檔,其中又有相對定位父級2和3,這個時候我們怎么求div1到文檔的距離呢?通過觀察,我們可以知道到文檔的距離,正好等於div1到它的定位父級div2的距離加上div2到它的定位父級div3的距離,再加上div3到文檔的距離,也就是圖中的1+2+3;所以我們可以先求出這個元素到自己的定位父級2的距離,然后再求出它的定位父級2到自己定位父級3的距離。依次到最后就會求得最終的到文檔的距離。(body的offsetParent不存在)

我們可以總結出這樣的代碼

 // obj是一個載體,用來放每個定位父級,是在改變的,比如上面的那張圖來看,一開始它是div1,當計算出div1到div2的距離的時候,再把它變成div2,再求div2到定位父級div3的距離。依次循環到最后沒有定位父級了,它就變成null了,然后停止了循環
var left = 0; 
while (obj) {    // 當這個元素節點存在的時候循環下面的代碼
    left += obj.offsetLeft;  // 把每個元素定位父級的距離都累加起來
    obj = obj.offsetParent;    // 把當前的元素賦給obj 
}

為了也能求出豎直方向上到文檔的距離,也為了更方便,我們可以封裝成一個函數:

    function getPos(obj) { 
        var pos = {left:0, top:0};
        while (obj) {
            pos.left += obj.offsetLeft;
            pos.top += obj.offsetTop;
            obj = obj.offsetParent;
        }       
        return pos;       
    }

 

這個函數會經常用到,像我們的瀑布流中,也是需求的。

最后添加個筆記:

offsetWidth \ clientWidth

style.width : width(樣式寬 帶單位)
clientWidth : width+padding(不帶單位 可視區寬)
offsetWidth:width+padding+border (占位置寬)

 

好啦,希望今天的分享能帶給大家新的體會。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM