節點操做

1.節點操做

1.1 爲何學節點操做

獲取元素一般使用兩種方式:
1. 利用 DOM 提供的方法獲取元素         
 document.getElementById() 
node

    document.getElementsByTagName() 數組

document.querySelector  等瀏覽器

邏輯性不強、繁瑣 app

2. 利用節點層級關係獲取元素
利用父子兄節點關係獲取元素
函數

邏輯性強, 可是兼容性稍差 this


這兩種方式均可以獲取元素節點,咱們後面都會使用,可是節點操做更簡單

spa

 

1.2. 節點概述

​   網頁中的全部內容都是節點(標籤、屬性、文本、註釋等),在DOM 中,節點使用 node 來表示。code

  ​ HTML DOM 樹中的全部節點都可經過 JavaScript 進行訪問,全部 HTML 元素(節點)都可被修改,也能夠建立或刪除。blog

 

   通常地,節點至少擁有nodeType(節點類型)、nodeName(節點名稱)和nodeValue(節點值)這三個基本屬性。事件

 1.元素節點  nodeType  爲 1
 2.屬性節點  nodeType  爲 2
 3.文本節點  nodeType  爲 3 (文本節點包含文字、空格、換行等)
 咱們在實際開發中,節點操做主要操做的是元素節點

 

1.3. 節點層級

​ 利用 DOM 樹能夠把節點劃分爲不一樣的層級關係,常見的是父子兄層級關係

 

 

1.4.1. 父級節點

1. 父級節點 

 node.parentNode

 

 1>parentNode 屬性可返回某節點的父節點,注意是最近的一個父節點
 2>若是指定的節點沒有父節點則返回 null

  <div class="demo">
        <div class="box">
            <span class="erweima">×</span>
        </div>
    </div>
    <script>
        // 1. 父節點 parentNode
        var erweima = document.querySelector('.erweima');
        // var box = document.querySelector('.box');
        // 獲得的是離元素最近的父級節點(親爸爸) 若是找不到父節點就返回爲 null
        console.log(erweima.parentNode);
    </script>

1.4. 2子節點

1.全部子節點

 1. parentNode.childNodes(標準) 

parentNode.childNodes 返回包含指定節點的子節點的集合,該集合爲即時更新的集合。
注意:返回值裏面包含了全部的子節點,包括元素節點,文本節點等。
若是隻想要得到裏面的元素節點,則須要專門處理。 因此咱們通常不提倡使用childNodes

2. 子元素節點

 2. parentNode.children(非標準) 

parentNode.children 是一個只讀屬性,返回全部的子元素節點。它只返回子元素節點,其他節點不返 回 (這個是咱們重點掌握的)。
雖然children 是一個非標準,可是獲得了各個瀏覽器的支持,所以咱們能夠放心使用

<ul>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
    </ul>
    <script>
        // DOM 提供的方法(API)獲取
        var ul = document.querySelector('ul');
        var lis = ul.querySelectorAll('li');
        // 1. 子節點  childNodes 全部的子節點 包含 元素節點 文本節點等等
        console.log(ul.childNodes);
        console.log(ul.childNodes[0].nodeType);
        console.log(ul.childNodes[1].nodeType);
        // 2. children 獲取全部的子元素節點 也是咱們實際開發經常使用的
        console.log(ul.children);
    </script>

3.第一個子節點

 3. parentNode.firstChild 

firstChild 返回第一個子節點,找不到則返回null。一樣,也是包含全部的節點。

4.最後一個子節點

4.parentNode.lastChild 

lastChild 返回最後一個子節點,找不到則返回null。一樣,也是包含全部的節點。

5.第一個子元素節點

 5. parentNode.firstElementChild

firstElementChild  返回第一個子元素節點,找不到則返回null。 
 6.最後一個子元素節點

 6. parentNode.lastElementChild  

lastElementChild 返回最後一個子元素節點,找不到則返回null。  
注意:這兩個方法有兼容性問題,IE9 以上才支持。

實際開發中,firstChild 和 lastChild 包含其餘節點,操做不方便,而 firstElementChild 和 lastElementChild 又有兼容性問題,那麼咱們如何獲取第一個子元素節點或最後一個子元素節點呢?
解決方案:
1. 若是想要第一個子元素節點,可使用 parentNode.chilren[0] 
2. 若是想要最後一個子元素節點,可使用 parentNode.chilren[parentNode.chilren.length - 1]

 

<ol>
        <li>我是li1</li>
        <li>我是li2</li>
        <li>我是li3</li>
        <li>我是li4</li>
        <li>我是li5</li>
    </ol>
    <script>
        var ol = document.querySelector('ol');
        // 1. firstChild 第一個子節點 無論是文本節點仍是元素節點
        console.log(ol.firstChild);
        console.log(ol.lastChild);
        // 2. firstElementChild 返回第一個子元素節點 ie9才支持
        console.log(ol.firstElementChild);
        console.log(ol.lastElementChild);
        // 3. 實際開發的寫法  既沒有兼容性問題又返回第一個子元素
        console.log(ol.children[0]);
        console.log(ol.children[ol.children.length - 1]);
    </script>

1.5兄弟節點

1.下一個兄弟節點

 1. node.nextSibling   

nextSibling 返回當前元素的下一個兄弟元素節點,找不到則返回null。一樣,也是包含全部的節點。

2.上一個兄弟節點

 2. node.previousSibling 

previousSibling 返回當前元素上一個兄弟元素節點,找不到則返回null。一樣,也是包含全部的節點。

<div>我是div</div>
    <span>我是span</span>
    <script>
        var div = document.querySelector('div');
        // 1.nextSibling 下一個兄弟節點 包含元素節點或者 文本節點等等
        console.log(div.nextSibling);
        console.log(div.previousSibling);
        // 2. nextElementSibling 獲得下一個兄弟元素節點
        console.log(div.nextElementSibling);
        console.log(div.previousElementSibling);
    </script>

3.下一個兄弟元素節點(有兼容性問題)

3. node.nextElementSibling 

nextElementSibling 返回當前元素下一個兄弟元素節點,找不到則返回null

4.上一個兄弟元素節點(有兼容性問題)

4. node.previousElementSibling 

previousElementSibling 返回當前元素上一個兄弟節點,找不到則返回null。 
注意:這兩個方法有兼容性問題, IE9 以上才支持。

 

5.問:如何解決兼容性問題 ?

答:本身封裝一個兼容性的函數

 

function getNextElementSibling(element){ 
var el = element;
while (el = el.nextSibling) {
if (el.nodeType === 1) {
return el;
}
}
return null;
}

1.6 .1建立節點

document.createElement('tagName') 

document.createElement() 方法建立由 tagName 指定的 HTML 元素。由於這些元素原先不存在, 是根據咱們的需求動態生成的,因此咱們也稱爲動態建立元素節點

1.6.2添加節點

 1. node.appendChild(child) 

node.appendChild() 方法將一個節點添加到指定父節點的子節點列表末尾。相似於 CSS 裏面的 after 僞元素。

 2. node.insertBefore(child, 指定元素)

node.insertBefore() 方法將一個節點添加到父節點的指定子節點前面。相似於 CSS 裏面的 before 僞元素。

<ul>
        <li>123</li>
    </ul>
    <script>
        // 1. 建立節點元素節點
        var li = document.createElement('li');
        // 2. 添加節點 node.appendChild(child)  node 父級  child 是子級 後面追加元素
        var ul = document.querySelector('ul');
        ul.appendChild(li);
        // 3. 添加節點 node.insertBefore(child, 指定元素);
        var lili = document.createElement('li');
        ul.insertBefore(lili, ul.children[0]);
        // 4. 咱們想要頁面添加一個新的元素 : 1. 建立元素 2. 添加元素
    </script>

 

1.7 刪除節點

 node.removeChild(child) 

node.removeChild() 方法從 DOM 中刪除一個子節點,返回刪除的節點。

<button>刪除</button>
    <ul>
        <li>熊大</li>
        <li>熊二</li>
        <li>光頭強</li>
    </ul>
    <script>
        // 1.獲取元素
        var ul = document.querySelector('ul');
        var btn = document.querySelector('button');
        // 2. 刪除元素  node.removeChild(child)
        // ul.removeChild(ul.children[0]);
        // 3. 點擊按鈕依次刪除裏面的孩子
        btn.onclick = function() {
            if (ul.children.length == 0) {
                this.disabled = true;
            } else {
                ul.removeChild(ul.children[0]);
            }
        }
    </script>

1.8 複製(克隆)節點

 node.cloneNode() 

node.cloneNode() 方法返回調用該方法的節點的一個副本。

注意:
1. 若是括號參數爲空或者爲 false ,則是淺拷貝,即只克隆複製節點自己,不克隆裏面的子節點。
2. 若是括號參數爲 true ,則是深度拷貝,會複製節點自己以及裏面全部的子節點。

 <ul>
        <li>1111</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        // 1. node.cloneNode(); 括號爲空或者裏面是false 淺拷貝 只複製標籤不復制裏面的內容
        // 2. node.cloneNode(true); 括號爲true 深拷貝 複製標籤複製裏面的內容
        var lili = ul.children[0].cloneNode(true);
        ul.appendChild(lili);
    </script>

1.9 建立元素的三種方式

 1>document.write()
 2>innerHTML
 3>document.createElement()

區別
1. document.write 是直接將內容寫入頁面的內容流,會致使頁面所有重繪
2. innerHTML 是將內容寫入某個 DOM 節點,不會致使頁面所有重繪
3. innerHTML 複製節點的時候,不會複製原先節點的事件,會存在內存泄露問題
4. 若是頁面建立元素不少,建議使用 innerHTML 因其效率更高(不要拼接字符串,採起數組形式拼接)
5. 若是頁面建立元素較少,建議使用 createElement()
總結:不一樣瀏覽器下,innerHTML 效率要比 creatElement 高

<script>
        // 三種建立元素方式區別 
        // 1. document.write() 建立元素  若是頁面文檔流加載完畢,再調用這句話會致使頁面重繪
         var btn = document.querySelector('button');
         btn.onclick = function() {
             document.write('<div>123</div>');
         }

        // 2. innerHTML 建立元素
        var inner = document.querySelector('.inner');
         for (var i = 0; i <= 100; i++) {
             inner.innerHTML += '<a href="#">百度</a>'
         }
        var arr = [];
        for (var i = 0; i <= 100; i++) {
            arr.push('<a href="#">百度</a>');
        }
        inner.innerHTML = arr.join('');
        // 3. document.createElement() 建立元素
        var create = document.querySelector('.create');
        for (var i = 0; i <= 100; i++) {
            var a = document.createElement('a');
            create.appendChild(a);
        }
    </script>

innerTHML和createElement效率對比

innerHTML字符串拼接方式(效率低)

 

<script>
    function fn() {
        var d1 = +new Date();
        var str = '';
        for (var i = 0; i < 1000; i++) {
            document.body.innerHTML += '<div style="width:100px; height:2px; border:1px solid blue;"></div>';
        }
        var d2 = +new Date();
        console.log(d2 - d1);
    }
    fn();
</script>

createElement方式(效率通常)

<script>
    function fn() {
        var d1 = +new Date();

        for (var i = 0; i < 1000; i++) {
            var div = document.createElement('div');
            div.style.width = '100px';
            div.style.height = '2px';
            div.style.border = '1px solid red';
            document.body.appendChild(div);
        }
        var d2 = +new Date();
        console.log(d2 - d1);
    }
    fn();
</script>

innerHTML數組方式(效率高)

<script>
    function fn() {
        var d1 = +new Date();
        var array = [];
        for (var i = 0; i < 1000; i++) {
            array.push('<div style="width:100px; height:2px; border:1px solid blue;"></div>');
        }
        document.body.innerHTML = array.join('');
        var d2 = +new Date();
        console.log(d2 - d1);
    }
    fn();
</script>
相關文章
相關標籤/搜索