DOM知識點總結

什麼是DOM

DOM(文檔對象模型)是針對HTML和XML的文檔的一個API ,DOM描繪了一個層次化的節點樹,允許開發人員添加,修改和刪除頁面中的一部分。

節點類型

DOM1定義了一個Node接口,該接口由DOM中所有的節點類型實現。節點類型由在Node類型中定義的12個數值常量來表示,任何節點類型必居其一:

  • Node.ELEMENT_NODE(1)
  • Node.ATTRIBUTE_NODE(2)
  • Node.TEXT_NODE(3)
  • Node.CDATA_SECTION_NODE(4)
  • Node.ENTITY_REFRENCE_NODE(5)
  • Node.ENTITY_NODE(6)
  • Node.PROCESSION_INSTRUCTION_NODE(7)
  • Node.COMMENT_NODE(8)
  • Node.DOCUMENT_NODE(9)
  • Node.DOCUMENT_TYPE_NODE(10)
  • Node.DOCUMENT_FRAGMENT_NODE(11)
  • Node.NOTATION_NODE(12)

每個節點都有一個nodeType屬性,通過比較上面這些常量可以很容易知道節點的類型,但是由於IE瀏覽器並沒有公開Node類型,因此最好還是將nodeType與數字值進行比較

if (someNode.nodeType === 1) {
  console.log('this is a element');
}

節點屬性

JavaScript中的每個節點都繼承自Node類型,因此每個節點都有相同的基本屬性和方法。

nodeName和nodeValue屬性

可以使用nodeNamenodeValue來了解節點的具體信息。這兩個屬性值完全取決於節點的類型,在使用之前最好先像下面這樣進行檢測一下:

if (someNode.nodeType === 1) {
  let value = someNode.nodeName; // nodeName的值是元素的標籤名
}

像上面這樣,首先檢測這個節點的類型,看它是不是一個元素,如果是便獲取它的nodeName的值,對於元素類型的節點來說,nodeName的值是這個元素的標籤名,而nodeValue的值始終是null

childNodes屬性

每個節點都有一個childNodes屬性,這個屬性裏面保存着一個NodeList對象NodeList是一個類數組的對象,裏面保存着一組有序的節點。可以通過位置來訪問這些節點。這個NodeList雖然也有length屬性,但是它並不是Array的實例。NodeList的獨特之處在於,它實際上是根據當前DOM結構進行查詢的結果。因此DOM結構的變化可以在NodeList中反應出來。下面的例子展示瞭如何獲取NodeList中保存的節點:

let firstChild = someNode,childNodes[0];
let secondChild = someNode.childNodes.item(1);
let count = someNode.childNodes.length;

在訪問NodeList中保存的節點時,使用[]或者是item()方法都可以,由於使用[]比較像數組的語法,所以更受青睞。

previousSibling和nextSibling屬性

childNodes列表中的每個節點相互之間都是同胞節點。通過使用列表中的previousSiblingnextSibling屬性可以訪問列表中的其他節點。列表中的第一個節點的previousSibling屬性值是null,最後一個節點的nextSibling屬性值爲null。如下所示:

if (someNode.nextSibling === null ) {
  console.log('this.is the last node');
} else if (someNode.previousSibling === null) {
  console.log('this is the first node');
}

parentNode,firstChild,lastChild屬性

每個節點都有一個parentNode屬性,這個屬性指向文檔樹中的父節點。包含着childNodes中的所有節點都有一個相同的父節點,因此它們的parentNode屬性指向同一個節點。父節點與childNodes列表中的第一個節點最後一個節點也有存在着特殊關係。父節點的firstChildlastChild屬性分別指向列表中的第一個子節點最後一個字節點。其中someNode.fristNode的值等於someNode.childNodes[0]。而someNode.lastNode的值等於someNode.childNodes[someNode.childNodes.length - 1]的值。在只有一個子節點的情況下,firstChild和lastChild屬性指向同一個值在沒有子節點的情況下,firstChild和lastChild屬性值都爲null。下圖向我們表明了各節點之間的關係:
在這裏插入圖片描述

ownerDocument屬性

所有節點擁有的最後一個屬性是ownerDocument屬性,該屬性指向表示整個文檔的文檔節點

hasChildNodes()方法

hasChildNodes()方法在節點擁有子節點的情況下會返回true,這比查詢childNodes的length屬性更方便快捷。

操作節點

因爲關係指針都是隻讀的,所以DOM提供了一些操作節點的方法。

appendChild()

appendChild()用於向childNodes列表的末尾添加一個節點。添加成功後,childNodes列表中新增的節點,父節點以及以前的最後一個節點的關係指針都會進行更新,更新完成後,appendChild()返回新增的節點

let returnedNode = someNode.appendChild(newNode);
console.log(returnedNode === newNode);// true
console.log(someNode.lastChild === newNode); // true

如果appendChild()操作的節點本身是文檔樹的一部分,那麼這個節點就會從當前位置移動到childNodes列表的最後一位

insertBefore()

如果想把節點插到特定的位置,此時就需要使用insertBefore()方法,這個方法接受兩個參數:要插入的節點作爲參照的節點insertBefore()會將節點插入到參照節點的前面。同時返回新插入的節點

// 當參照節點是null的時候,插入成爲最後一個節點。
let returnedNode = someNode.insertBefore(newNode, null);
console.log(someNode.lastChild === returnedNode); // true

// 插入成爲第一個節點
let returnedNode = someNode.insertBefor(newNode, someNode.firstChild);
console.log(someNode.firstChild === returnedNode); // true

replaceChild()和removeChild()

  • replaceChild()
    replaceChild()方法用來替換節點,它接受兩個參數:要插入的節點要替換的節點。並返回要替換的節點,而這個要替換的節點會被從DOM樹上刪除
// 替換第一個節點
let returnedNode = someNode.replaceChild(newNode, someNode.firstChild);

// 替換最後一個節點
let returnedNode = someNode.replaceChild(newNode, someNode.lastChild);
  • removeChild()
    如果你只想移除某個節點,而並不像替換它,則可以使用removeChild()方法。這個方法接受一個值,就是要移除的節點,這個要移除的節點會被作爲該方法的返回值進行返回
// 移除第一個節點
let returnedNode = someNode.removeChild(someNode.firstChild);
// 移除最後一個節點
let returnedNde = someNode,removeChild(someNode.lastChild)

cloneNode()

這個方法是所有的節點都有的,用於創建調用這個方法的節點的一個副本。cloneNode()方法接受一個布爾值參數,在參數是true的時候,表示執行深複製,也就是複製節點本身和整個子節點樹。值爲false,表示執行淺複製,即只複製這個節點本身。複製後返回的節點副本屬於文檔所有,但是並沒有給它指定父元素,因此這個副本就變成了一個“孤兒”。除非將它通過appendChild()insertBefore()replaceChild()將它插入到文檔樹中。
假如有以下的HTML結構:

<ul>
  <li>item1</li>
  <li>item2</li>
  <ii>item3<li>
</ul>

假設我們以及把ul元素的引用儲存在了myList變量中,那麼通過下面代碼就可以看到cloneChild()兩種模式的區別。

let deepList = myList.cloneChild(true);
console.log(deepList.childNodes.lengh); //3 (IE < 9) 或 7(其他瀏覽器)

let shallowList = myList.cloneChild(false);
console.log(shallowList.childNodes.length); // 0

查找元素

說到常見的DOM應用,恐怕就要數取得特定的幾個或某個元素的引用,從而進行操作了。取得元素的方法可以使用定義在document對象中的一些方法。

getElementById()

getElementById()接受一個參數,這個參數是要取得的元素的id值**。這裏的id值必須與元素的id屬性值一模一樣**。以下面的元素爲例:

<div id="myDiv">item1</div>

// 可以使用下面的方法獲取到這個div元素
let element = document.getElementById('myDiv');

如果頁面中有多個id值一樣的元素,getElementById()只會返回第一次出現的元素

getElementsByTagName()

這個方法接受一個參數,即要獲取的元素的標籤名,而返回的是零個或多個元素的NodeList。

// 獲取頁面中的所有的img元素,並將返回的集合保存咋images變量中
let images = document.getElementsByTagName('img');

// 此時的images變量和NodeList很類似,可以使用[]或item()來訪問其中的項
console.log(images.length); //img元素的數量
console.log(images[0].src); // 第一個img元素的src屬性值

getElementsByName()

這個方法會返回帶有給定name屬性的所有元素。最常使用該方法來獲取單選按鈕,不過要求所有的單元按鈕具備相同的name屬性值

<div>
  <ul>
     <li> <input type="radio" name="color" value="red" id="colorRed"/></li>
     <li> <input type="radio" name="color" value="green" id="colorGreen"/></li>
     <li> <input type="radio" name="color" value="blue" id="colorBlue"/></li>
   <ul>
</div>

// 獲取name值爲color的單選按鈕元素
var radio = document.getElementsByName("color");

querySelector()

querySelector()接受一個css選擇符,返回與該模式匹配的第一個元素,如果沒有,就返回null

// 獲取body 元素
var body = document.querySelector("body");

// 獲取id爲#myDiv的元素
var div = dosument.querySelector("#myDiv")

// 獲取類爲selector的元素
var element = document.querySelector(".selector")

// 獲取類爲button的第一個ing元素
var img = document.querySelector("img.button")

querySelectorAll()

querySelectorAll()方法接受的參數與querySelector()一樣,但返回的是所有匹配的元素,而不是第一個元素。

// 獲取類爲selector的元素
var elements = document.querySelectorAll(".selector")
// 獲取p元素中的所有strong元素
var strongs = document.querySelectorAll("p strong");
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章