文檔對象模型
文檔對象模型(doucment object model,dom)是表示文檔(如html文檔、xml文檔)和訪問、操作構成文檔的各種元素的應用程序接口。在dom中,html文檔的層次結構被表示成樹形結構。樹的節(jié)點表示文檔中的各種內容。
Node類型
Node是一個接口,中文叫節(jié)點,很多類型的DOM元素都是繼承于它,都共享著相同的基本屬性和方法。常見的Node有 element,text,attribute,comment,document 等(所以要注意 節(jié)點 和 元素 的區(qū)別,元素屬于節(jié)點的一種)。
Node有一個屬性 nodeType 表示Node的類型,它是一個整數(shù),其數(shù)值分別表示相應的Node類型,具體如下:
- Node.ELEMENT_NODE:1
- Node.ATTRIBUTE_NODE:2
- Node.TEXT_NODE:3
- Node.CDATA_SECTION_NODE:4
- Node.ENTITY_REFERENCE_NODE:5
- Node.ENTITY_NODE:6
- Node.PROCESSING_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
假設我們要判斷一個Node是不是元素,我們可以這樣判斷
if(someNode.nodeType == 1){
console.log("Node is a element");
}
這些Node類型中,我們最常用的就是element,text,attribute,comment,document這幾種類型:
- Element提供了對元素標簽名,子節(jié)點和特性的訪問;
- Text表示文本節(jié)點,它包含的是純文本內容,不能包含html代碼,但可以包含轉義后的html代碼;
- Attr類型表示元素的特性,相當于元素的attributes屬性中的節(jié)點;
- Comment表示HTML文檔中的注釋;
- Document表示文檔,在瀏覽器中,document對象是HTMLDocument的一個實例,表示整個頁面,它同時也是window對象的一個屬性;
節(jié)點創(chuàng)建型api
1. createElement
createElement通過傳入指定的一個標簽名來創(chuàng)建一個元素,使用如下:
var newDiv = document.createElement("div");
2. createTextNode
createTextNode用來創(chuàng)建一個文本節(jié)點,使用如下:
var newtext = document.createTextNode("動態(tài)添加一些文本");
3. cloneNode
cloneNode方法返回調用該方法的節(jié)點的一個副本,使用如下:
var p = document.getElementById("para1"),
var p_prime = p.cloneNode(true);
p_prime.id = "p_prime";
注意:為了防止一個文檔中出現(xiàn)兩個ID重復的元素,使用cloneNode()方法克隆的節(jié)點在需要時應該指定另外一個與原ID值不同的ID
4.createDocumentFragment
DocumentFragment是DOM節(jié)點。它們不是主DOM樹的一部分。通常的用例是創(chuàng)建文檔片段,將元素附加到文檔片段,然后將文檔片段附加到DOM樹。在DOM樹中,文檔片段被其所有的子元素所代替。
因為文檔片段存在于內存中,并不在DOM樹中,所以將子元素插入到文檔片段時不會引起頁面回流。因此,使用文檔片段document fragments 通常會起到優(yōu)化性能的作用。使用如下:
document.getElementById("btnAdd").onclick = function(){
var list = document.getElementById("list");
var fragment = document.createDocumentFragment();
for(var i = 0;i < 100; i++){
var li = document.createElement("li");
li.textContent = i;
fragment.appendChild(li);
}
list.appendChild(fragment);
}
頁面修改型API
創(chuàng)建型api它們只是創(chuàng)建節(jié)點,并沒有真正修改到頁面內容,而是要調用appendChild來將其添加到文檔樹中。
修改頁面內容的api主要包括:appendChild,insertBefore,removeChild,replaceChild。
1.appendChild
appendChild方法將一個節(jié)點添加到指定父節(jié)點的子節(jié)點列表末尾,調用方法如下:
// 創(chuàng)建一個新的段落p元素,然后添加到body的最尾部
var p = document.createElement("p");
document.body.appendChild(p);
如果被插入的節(jié)點已經存在于當前文檔的文檔樹中,則那個節(jié)點會首先從原先的位置移除,然后再插入到新的位置.
2.insertBefore
insertBefore方法在參考節(jié)點之前插入一個節(jié)點作為一個指定父節(jié)點的子節(jié)點。
var insertedElement = parentElement.insertBefore(newElement, referenceElement);
如果referenceElement為null則newElement將被插入到子節(jié)點的末尾。如果newElement已經在DOM樹中,newElement首先會從DOM樹中移除。
- insertedElement 是被插入的節(jié)點,即 newElement
- parentElement 是新插入節(jié)點的父節(jié)點
- newElement 是被插入的節(jié)點
- referenceElement 在插入newElement之前的那個節(jié)點
- 如果referenceElement為null則newElement將被插入到子節(jié)點的末尾。如果newElement已經在DOM樹中,newElement首先會從DOM樹中移除。
例子:
<div id="parentElement">
<span id="childElement">foo bar</span>
</div>
<script>
var sp1 = document.createElement("span");
var sp2 = document.getElementById("childElement");
var parentDiv = sp2.parentNode;
parentDiv.insertBefore(sp1, sp2);
</script>
3.removeChild
removeChild方法從DOM中刪除一個子節(jié)點。返回刪除的節(jié)點。
var oldChild = node.removeChild(child);
- child是要移除的那個子節(jié)點.
- node是child`的父節(jié)點.
- oldChild保存對刪除的子節(jié)點的引用oldChild === child.
被移除的這個子節(jié)點仍然存在于內存中,只是沒有添加到當前文檔的DOM樹中,因此,你還可以把這個節(jié)點重新添加回文檔中,當然,實現(xiàn)要用另外一個變量來保存這個節(jié)點的引用. 如果使用上述語法中的第二種方法, 即沒有使用 oldChild 來保存對這個節(jié)點的引用, 則認為被移除的節(jié)點已經是無用的。
4.replaceChild
用指定的節(jié)點替換當前節(jié)點的一個子節(jié)點,并返回被替換掉的節(jié)點。
var replacedNode = parentNode.replaceChild(newChild, oldChild);
- newChild 用來替換 oldChild 的新節(jié)點。如果該節(jié)點已經存在于DOM樹中,則它會被從原始位置刪除。
- oldChild 被替換掉的原始節(jié)點。
- replacedNode 和oldChild相等。
節(jié)點查詢型API
1.document.getElementById
返回一個匹配特定 ID,如果不存在該元素,則返回null。
var element = document.getElementById(id);
- element是一個Element 對象。如果當前文檔中擁有特定ID的元素不存在則返回null.
- id是大小寫敏感的字符串,代表了所要查找的元素的唯一ID。所以document.getElementById("Main")無法獲取到元素<div id="main">,因為'M'和'm'是不一樣的。
2.document.getElementsByTagName
這個接口根據元素標簽名獲取元素,返回一個即時的HTMLCollection類型。
var elements = document.getElementsByTagName(name);
- elements是一個由發(fā)現(xiàn)的元素出現(xiàn)在樹中的順序構成的動態(tài)的HTML集合 HTMLCollection
- name 是一個代表元素的名稱的字符串。特殊字符 "*" 代表了所有元素。
3.document.getElementsByName
getElementsByName主要是通過指定的name屬性來獲取元素,它返回一個即時的NodeList對象。
var elements = document.getElementsByName(name)
- elements是一個NodeList對象是一個節(jié)點的集合
- name是元素的name屬性的值。
4.document.getElementsByClassName
返回一個包含了所有指定類名的子元素的類數(shù)組對象。當在document對象上調用時,會搜索整個DOM文檔,包含根節(jié)點。你也可以在任意元素上調用getElementsByClassName()方法,它將返回的是以當前元素為根節(jié)點,所有指定類名的子元素。
var elements = document.getElementsByClassName(names);
- elements 是一個實時集合,包含了找到的所有元素。
- names 是一個字符串,表示要匹配的類名列表;類名通過空格分隔
- getElementsByClassName 可以在任何元素上調用,不僅僅是 document。 調用這個方法的元素將作為本次查找的根元素.
5.document.querySelector
返回文檔中匹配指定的選擇器組的第一個元素(使用深度優(yōu)先先序遍歷文檔的節(jié)點 | 并且通過文檔標記中的第一個元素,并按照子節(jié)點數(shù)量的順序迭代順序節(jié)點)。
var element = document.querySelector(selectors);
- element 是一個element 對象(DOM 元素)。
- selectors是一個字符串,包含一個或是多個CSS 選擇器,多個則以逗號分隔。
如果沒有找到匹配元素,則返回 null,如果找到多個匹配元素,則返回第一個匹配到的元素。
如果選擇器是一個 ID,并且這個 ID 在文檔中錯誤地使用了多次,那么返回第一個匹配該 ID 的元素。
6.document.querySelectorAll
返回與指定的選擇器組匹配的文檔中的元素列表 (使用深度優(yōu)先的先序遍歷文檔的節(jié)點)。返回的對象是 NodeList。
var elementList = document.querySelectorAll(selectors);
- elementList 是一個靜態(tài)的NodeList 類型的對象.
- selectors是一個由逗號連接的包含一個或多個CSS選擇器的字符串.
- 如果selectors參數(shù)中包含CSS偽元素,則返回一個空的elementList。
元素屬性型api
1.setAttribute
設置指定元素上的一個屬性值。如果屬性已經存在,則更新該值; 否則將添加一個新的屬性用指定的名稱和值。
element.setAttribute(name, value);
- name 是表示屬性名稱的字符串
- value 是屬性的新值
2.getAttribute
getAttribute() 返回元素上一個指定的屬性值。如果指定的屬性不存在,則返回 null 或 "" (空字符串)
var attribute = element.getAttribute(attributeName);
- attribute 是一個包含 attributeName 屬性值的字符串。
- attributeName 是你想要獲取的屬性值的屬性名稱。