DOM的常見操作API
DOM的常見操作API
文件物件模型 (DOM) 是HTML和XML文件的程式設計介面。它提供了對文件的結構化的表述,並定義了一種方式可以使從程式中對該結構進行訪問,從而改變文件的結構,樣式和內容。DOM 將文件解析為一個由節點和物件(包含屬性和方法的物件)組成的結構集合。一個web頁面是一個文件。DOM是web頁面的完全的面向物件表述,它能夠使用如 JavaScript等指令碼語言進行修改。
一、DOM中常用的Node資料型別
1、Document
Document表示文件,在瀏覽器中,document物件是HTMLDocument的一個例項,表示整個頁面,它同時也是window物件的一個屬性。Document有下面的特性:
(2)nodeName為#document
(3)nodeValue為null
(4)parentNode為null
(5)子節點可能是一個DocumentType或Element
2、Element型別
Element提供了對元素標籤名,子節點和特性的訪問,我們常用HTML元素比如div,span,a等標籤就是element中的一種。Element有下面幾條特性:
(1)nodeType為1
(2)nodeName為元素標籤名,tagName也是返回標籤名
(3)nodeValue為null
(4)parentNode可能是Document或Element
(5)子節點可能是Element,Text,Comment,Processing_Instruction,CDATASection或EntityReference
Text表示文字節點,它包含的是純文字內容,不能包含html程式碼,但可以包含轉義後的html程式碼。Text有下面的特性:
(1)nodeType為3
(2)nodeName為#text
(3)nodeValue為文字內容
(4)parentNode是一個Element
(5)沒有子節點
4、Attr型別
Attr型別表示元素的特性,相當於元素的attributes屬性中的節點,它有下面的特性:
(1)nodeType值為2
(2)nodeName是特性的名稱
(3)nodeValue是特性的值
(4)parentNode為null
5、Comment型別
Comment表示HTML文件中的註釋,它有下面的幾種特徵:
(2)nodeName為#comment
(3)nodeValue為註釋的內容
(4)parentNode可能是Document或Element
(5)沒有子節點
6、DocumentFragment型別
DocumentFragment是所有節點中唯一一個沒有對應標記的型別,它表示一種輕量級的文件,可能當作一個臨時的倉庫用來儲存可能會新增到文件中的節點。DocumentFragment有下面的特性:
(1)nodeType為11
(2)nodeName為#document-fragment
(3)nodeValue為null
(4)parentNode為null
7、nodeList
nodeList 是一個元素的陣列,如從 getElementsByTagName() 方法返回的就是這種型別。 nodeList 中的條目由通過下標有兩種方式進行訪問:list.item(1)和list[1]。
兩種方式是等價的,第一種方式中 item() 是 nodeList 物件中的單獨方法。 後面的方式則使用了經典的陣列語法來獲取列表中的第二個條目。
8、namedNodeMap
namedNodeMap 和陣列類似,但是條目是由name或index訪問的,雖然後一種方式僅僅是為了列舉方便,因為在 list 中本來就沒有特定的順序。 出於這個目的, namedNodeMap 有一個 item() 方法,你也可以從 namedNodeMap 新增或移除條目。
二、DOM中常用的API
1、節點建立型API
(1)createElement()
createElement()方法通過傳入指定的一個標籤名來建立一個元素,如果傳入的標籤名是一個未知的,則會建立一個自定義的標籤。
var li = document.createElement("li");
注意:使用createElement要注意:通過createElement建立的元素並不屬於html文件,它只是創建出來,並未新增到html文件中,要呼叫appendChild或insertBefore等方法將其新增到HTML文件樹中。
(2)createTextNode()
createTextNode()方法用來建立一個文字節點,createTextNode接收一個引數,這個引數就是文字節點中的文字,和createElement一樣,建立後的文字節點也只是獨立的一個節點,同樣需要appendChild將其新增到HTML文件樹中。
var textNode = document.createTextNode("textNode");
(3)cloneNode()
cloneNode()方法是用來返回呼叫方法的節點的一個副本,它接收一個bool引數,用來表示是否複製子元素。
var parent = document.getElementById("parentElement");
var parent1 = parent.cloneNode(true);// 傳入true
parent1.id = "parent1";
注意:
①和createElement一樣,cloneNode建立的節點只是遊離有html文件外的節點,要呼叫appendChild方法才能新增到文件樹中。
②如果複製的元素有id,則其副本同樣會包含該id,由於id具有唯一性,所以在複製節點後必須要修改其id。
③呼叫接收的bool引數最好傳入,如果不傳入該引數,不同瀏覽器對其預設值的處理可能不同。
④如果被複制的節點通過addEventListener或者比如onclick進行繫結事件,則副本節點不會繫結該事件;如果是內聯方式繫結,副本節點同樣會觸發事件。
(4)createDocumentFragment()
createDocumentFragment方法用來建立一個DocumentFragment。在前面我們說到DocumentFragment表示一種輕量級的文件,它的作用主要是儲存臨時的節點用來準備新增到文件中。createDocumentFragment方法主要是用於新增大量節點到文件中時會使用到。假設要迴圈一組資料,然後建立多個節點新增到文件中。
建立型API總結
建立型api主要包括createElement,createTextNode,cloneNode和createDocumentFragment四個方法,需要注意下面幾點:
①它們建立的節點只是一個孤立的節點,要通過appendChild新增到文件中;
②cloneNode要注意如果被複制的節點是否包含子節點以及事件繫結等問題;
③使用createDocumentFragment來解決新增大量節點時的效能問題。
2、節點查詢型API
(1)getElementById()
根據元素id返回元素,返回值是Element型別,如果不存在該元素,則返回null。
<body>
<div id="time">
2020.11.15
</div>
<script>
var timer = document.getElementById('time');
console.log(timer);
console.log(typeof timer);
console.dir(timer);
</script>
</body>
console.log 可以列印返回的元素物件,更好的檢視裡面的屬性和方法。
使用這個介面有幾點要注意:
①元素的Id是大小寫敏感的,一定要寫對元素的id;
②HTML文件中可能存在多個id相同的元素,則返回第一個元素;
③只從文件中進行搜尋元素,如果建立了一個元素並指定id,但並沒有新增到文件中,則這個元素是不會被查詢到的;
(2)getElementsByTagName()
根據元素標籤名獲取元素,返回一個即時的HTMLCollection型別。
使用該介面有幾點要注意:
①如果要對HTMLCollection集合進行迴圈操作,最好將其長度快取起來,因為每次迴圈都會去計算長度,暫時快取起來可以提高效率;
②如果沒有存在指定的標籤,該介面返回的不是null,而是一個空的HTMLCollection;
③“*”表示所有標籤;
(3)getElementsByName()
根據指定的name屬性來獲取元素,它返回一個即時的NodeList物件。
使用這個介面有幾點要注意:
①返回物件是一個即時的NodeList,它是隨時變化的;
②在HTML元素中,並不是所有元素都有name屬性,比如div是沒有name屬性的,但是如果強制設定div的name屬性,它也是可以被查詢到的;
③在IE中,如果id設定成某個值,然後傳入getElementsByName的引數值和id值一樣,則這個元素是會被找到的,所以最好不好設定同樣的值給id和name;
(4)getElementsByClassName()
根據元素的class返回一個即時的HTMLCollection。
使用這個介面有幾點要注意:
①返回結果是一個即時的HTMLCollection,會隨時根據文件結構變化;
②IE9以下瀏覽器不支援;
③如果要獲取2個以上classname,可傳入多個classname,每個用空格相隔;
(5)querySelector()和querySelectorAll()
根據css選擇器來查詢元素。
document.querySelector()返回第一個匹配的元素,如果沒有匹配的元素,則返回null。
document.querySelectorAll()在於它返回的是所有匹配的元素,而且可以匹配多個選擇符。
使用這個介面有幾點要注意:
①querySelectorAll也是通過深度優先搜尋,搜尋的元素順序和選擇器的順序無關
②返回的是一個非即時的NodeList,也就是說結果不會隨著文件樹的變化而變化
3、節點修改型API
(1)改變元素內容
①element.innerHTML()
獲取或修改起始位置到終止位置的全部內容,包括html標籤,同時保留空格和換行。
②element.innerText()
獲取或修改起始位置到終止位置的內容,但它去除html標籤,同時空格和換行也會去掉。
<html>
<head><title>innerHTML</title></head>
<body>
<div id="d1"><p id="p1">hello world </p></div>
<script>
var content = document.getElementById("d1");
alert(content.innerHTML);
alert(content.innerText)
</script>
</body>
</html>
通過IE瀏覽器開啟,彈出內容為 <p id="p1">hello world </p>
和 hello world。
通過 Firefox 瀏覽器開啟,彈出內容為 <p id="p1">hello world </p>
和 undefined。
通過 chrome 瀏覽器開啟,彈出內容為 <p id="p1">hello world </p>
和 hello world。
通過上面兩個示例,可以看出:innerHTML指的是從物件的起始位置到終止位置的全部內容,包括Html標籤。innerText 指的是從起始位置到終止位置的內容,但它去除Html標籤。
②element.value
獲取或修改某個按鈕、隱藏域、文字域等的值。
//建立文字框
UserName:<input type="text" name="uname" class="u">
//通過id獲取文字框內容
document.getElementById("name").value;
//通過標籤名文字框內容
document.getElementsByTagName("input")[0].value;
//通過name獲取文字框內容
document.getElementsByName("uname")[0].value;
//通過class獲取文字框內容
document.getElementsByClassName("u")[0].value
(2)改變元素屬性
①setAttribute()
根據名稱和值修改元素的特性。
element.setAttribute(name, value);
其中name是特性名,value是特性值。如果元素不包含該特性,則會建立該特性並賦值。
②getAttribute()
返回指定的特性名相應的特性值,如果不存在,則返回null或空字串。
var value = element.getAttribute("id");
③直接新增或修改節點屬性
//建立文字框
<input type="text" name="uname" class="u">
//給input元素新增id屬性
document.getElementsByTagName("input")[0].id="name";
4、節點關係型API
(1)父關係型api
①parentNode:每個節點都有一個parentNode屬性,它表示元素的父節點。Element的父節點可能是Element,Document或DocumentFragment。
②parentElement:返回元素的父元素節點,與parentNode的區別在於,其父節點必須是一個Element,如果不是,則返回null。
(2)兄弟關係型api
①previousSibling:節點的前一個節點,如果該節點是第一個節點,則為null。注意有可能拿到的節點是文字節點或註釋節點,與預期的不符,要進行處理一下。
②previousElementSibling:返回前一個元素節點,前一個節點必須是Element,注意IE9以下瀏覽器不支援。
③nextSibling:節點的後一個節點,如果該節點是最後一個節點,則為null。注意有可能拿到的節點是文字節點,與預期的不符,要進行處理一下。
④nextElementSibling:返回後一個元素節點,後一個節點必須是Element,注意IE9以下瀏覽器不支援。
(3)子關係型api
①childNodes:返回一個即時的NodeList,表示元素的子節點列表,子節點可能會包含文字節點,註釋節點等。
②children:一個即時的HTMLCollection,子節點都是Element,IE9以下瀏覽器不支援。
③firstNode:第一個子節點
④lastNode:最後一個子節點
⑤hasChildNodes方法:可以用來判斷是否包含子節點。
5、節點增刪型API
(1)appendChild()
將指定的節點新增到呼叫該方法的節點的子元素的末尾。
注意:如果被新增的節點是一個頁面中存在的節點,則執行後這個節點將會新增到指定位置,其原本所在的位置將移除該節點,也就是說不會同時存在兩個該節點在頁面上,相當於把這個節點移動到另一個地方。
(2)removeChild()
刪除指定的子節點並返回。
注意:如果被刪除的節點不是其子節點,則程式將會報錯,可以通過節點自己獲取節點的父節點然後將自身刪除。
(3)replaceChild()
使用一個節點替換另一個節點。oldChild是被替換的節點,newChild是替換的節點,可以是新的節點,也可以是頁面上的節點,如果是頁面上的節點,則其將被轉移到新的位置。
parent.replaceChild(newChild,oldChild);
(4)insertBefore()
新增一個節點到一個參照節點之前。parentNode表示新節點被新增後的父節點,newNode表示要新增的節點,refNode表示參照節點,新節點會新增到這個節點之前。
parentNode.insertBefore(newNode,refNode);