JavaScript DOM查詢,原生js實現元素子節點的獲取


  每個網頁都是一個dom樹,網頁中所有的內容都是這個樹上的一個節點。JavaScript的工作就是操作這些節點,對節點進行查增刪改操作,或是給節點綁定事件。

                                                               網頁

                                                    dom樹

要操作dom節點,首先要獲取到dom節點。這里我介紹幾個原生js獲取元素子節點的方法:

一、通過標簽的屬性值獲取后代節點 

以getElementBy開頭的方法,可以根據具體的屬性獲取元素的后代節點。這些方法不只會獲取子節點,他也會獲取到所有符合條件的后代節點。

方法 依據屬性 兼容性 其他
getElementById id

兼容性好,推薦使用

如果存在多個id相同的元素,只會返回第一個

getElementsByTagName 標簽名 不兼容ie8及以下版本  返回所有符合條件的元素的集合
getElementsByName name 不兼容ie8及以下版本  返回所有符合條件的元素的集合
getElementsByClassName class 不兼容ie8及以下版本 返回所有符合條件的元素的集合

 以getElementById為例,盡管有兩個id為’Jan‘的元素,但是只會獲取到第一個:

<html>
    <head>
    </head>
    <body>
        <p id='Jan' class='test'>1</p>
        <p id='Jan' class='test'>2</p>
        <p id='Mar'>3</p>
    </body>
    <script type="text/javascript">
        var j=document.getElementById('Jan');
        console.log(j);
    </script>
</html>

需要注意的是,在同一個文件中出現重復id是不符合規范的,應當盡量避免這樣使用。

如果將上面代碼中的getElementById('Jan')換成 getElementsByTagName('p')或者是getElementsByClassName('test')將會獲取到符合條件的結果集。

 

二、child屬性

每個dom元素都是一個對象,在dom元素對象中有四個專門用於獲取子元素的屬性:

屬性名 作用 其他
childNodes 獲取所有子節點 不推薦使用,如果有空格,會作為文本節點獲取到
child 獲取所有子節點 推薦使用
firstChild 獲取首個子節點 推薦使用
lastChild 獲取最后一個子節點 推薦使用

這四個屬性都不存在兼容性問題,除了childNodes之外都是比較好用的。

1. childNodes

childNodes屬性可以獲取元素的所有子節點,並封裝到一個數組中,可以通過下標來獲取某個子元素:

 

<html>
    <head>
    </head>
    <body>
        <div class="test" id="test">
          <p>1</p>
          <p>3</p>
          <p>5</p>
        </div>
    </body>
    <script>
        var a = document.getElementById("test");
        console.log(a.childNodes);
    </script>
</html>

但是childNodes屬性有一個問題,class=‘test’的div中只有3子節點,執行結果卻有7個節點:

因為根據在網頁中,標簽之間的回車空格等特殊字符屬於一個p元素,上面的div中輸入了4個回車,因此會多出四個text節點:

 

要解決這個問題有兩個方法:

方法一:去掉所有的回車空格等特殊字符,但是會影響程序的可讀性和代碼的規范。

方法二:動態過濾掉空白字符:

通過for循環遍歷對象中的所有元素,刪除純文本元素。

完整的代碼就是這樣:

        var a = document.getElementById("test");
        var b = a.childNodes;
        for(i=0;i<b.length;i++){
            if(b[i].nodeName == "#text"&& !/\s/.test(b.nodeValue)){
                a.removeChild(b[i]);
            }
        }

第二種方法每次查詢之前,都要先執行一段過濾代碼。這樣會影響程序的執行效率,因此childNodes屬性不建議使用。

 

2. children

相比childNodes,children屬性不會將空格作為文本節點獲取。因此就不需要額外的去除空格操作,獲取節點的方式和chlidNodes屬性相同。

還是用上面的代碼,將 a.childNodes 修改為 a.child 之后,會獲取到三個p元素,這就是通常希望得到的結果。

 

chilren和childNodes屬性存在的缺點是會獲取全部的子節點,某些情況下使用時需要篩選,不夠靈活。

 

3. firstChild&lastChild

firstChild會獲取首個子節點,相當於children[0]的效果。

lastChild會獲取最后一個子節點,相當於children[children.length-1]

 

三、querySelector方法,強烈推薦!

querySelector的參數是css選擇器,任何選擇器都可以作為它的參數,這樣就使得它非常方便靈活:

比如獲取class=‘test’的標簽下的第一個子元素,可以這樣寫querySelector('.test  > * '),也可以指定子元素的類型querySelector('.test  > span '),或者是:classquerySelector('.test  > #f_div')

還可以使用querySelectorAll方法,這樣會獲取所有滿足條件的元素,而不只是獲取第一個元素。

 

<div class="first">
    <span>張三</span>
</div>
<div id="second">
    <div id=f_div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
</div>
<script>
    //通過類選擇器獲取節點
    doucument.querySelector('.first');
    //通過id選擇器獲取節點
    doucument.querySelector('#second');
    //通過偽類選擇器獲取子節點
    document.querySelector('.first>span');
    //確認selectAll批量獲取節點
    document.querySelectorAll('#second>div');
</script>

總體來說,我比較推薦使用querySelector方法,因為它更加靈活,使用作為css選擇器進行選擇非常方便。當然querySelector方法不只可以獲取元素的子節點,它可以獲取任何節點。querySelector方法可以兼容到IE8,基本能滿足前端開發兼容性的需要。


免責聲明!

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



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