常用DOM API


Node

Node是一個接口,中文叫節點,很多類型的DOM元素都是繼承於它,都共享着相同的基本屬性和方法。常見的Node有 element,text,attribute,comment,document 等(所以要注意 節點 和 元素 的區別,元素屬於節點的一種)。

Node有一個屬性 nodeType 表示Node的類型,它是一個整數,其數值分別表示相應的Node類型,具體如下:

 
  1. {  
  2.     ELEMENT_NODE: 1, // 元素節點  
  3.     ATTRIBUTE_NODE: 2, // 屬性節點  
  4.     TEXT_NODE: 3, // 文本節點  
  5.     DATA_SECTION_NODE: 4,  
  6.     ENTITY_REFERENCE_NODE: 5,  
  7.     ENTITY_NODE: 6,  
  8.     PROCESSING_INSTRUCTION_NODE: 7,  
  9.     COMMENT_NODE: 8, // 注釋節點  
  10.     DOCUMENT_NODE: 9, // 文檔  
  11.     DOCUMENT_TYPE_NODE: 10,  
  12.     DOCUMENT_FRAGMENT_NODE: 11, // 文檔碎片  
  13.     NOTATION_NODE: 12,  
  14.     DOCUMENT_POSITION_DISCONNECTED: 1,  
  15.     DOCUMENT_POSITION_PRECEDING: 2,  
  16.     DOCUMENT_POSITION_FOLLOWING: 4,  
  17.     DOCUMENT_POSITION_CONTAINS: 8,  
  18.     DOCUMENT_POSITION_CONTAINED_BY: 16,  
  19.     DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 32  
  20. }  

 

 

NodeList

NodeList 對象是一個節點的集合,一般由 Node.childNodes 、 document.getElementsByName 和 document.querySelectorAll 返回的。

不過需要注意, Node.childNodes 、 document.getElementsByName 返回的 NodeList 的結果是實時的(此時跟HTMLCollection比較類似),而 document.querySelectorAll 返回的結果是固定的,這一點比較特殊。

舉例如下: 

 
  1. var childNodes = document.body.childNodes;  
  2. console.log(childNodes.length); // 如果假設結果是“2”  
  3. document.body.appendChild(document.createElement('div'));  
  4. console.log(childNodes.length); // 此時的輸出是“3”  

 

 

HTMLCollection

HTMLCollection是一個特殊的NodeList,表示包含了若干元素(元素順序為文檔流中的順序)的通用集合,它是實時更新的,當其所包含的元素發生改變時,它會自動更新。另外,它是一個偽數組,如果想像數組一樣操作它們需要像 Array.prototype.slice.call(nodeList, 2) 這樣調用。

節點查找API

  • document.getElementById :根據ID查找元素,大小寫敏感,如果有多個結果,只返回第一個;

  • document.getElementsByClassName :根據類名查找元素,多個類名用空格分隔,返回一個 HTMLCollection 。注意兼容性為IE9+(含)。另外,不僅僅是document,其它元素也支持 getElementsByClassName 方法;

  • document.getElementsByTagName :根據標簽查找元素, * 表示查詢所有標簽,返回一個 HTMLCollection 。

  • document.getElementsByName :根據元素的name屬性查找,返回一個 NodeList 。

  • document.querySelector :返回單個Node,IE8+(含),如果匹配到多個結果,只返回第一個。

  • document.querySelectorAll :返回一個 NodeList ,IE8+(含)。

  • document.forms :獲取當前頁面所有form,返回一個 HTMLCollection ;

節點創建API

節點創建API主要包括 createElement 、 createTextNode 、 cloneNode 和 createDocumentFragment 四個方法。

createElement

創建元素: 

 
  1. var elem = document.createElement("div");  
  2. elem.id = 'test';  
  3. elem.style = 'color: red';  
  4. elem.innerHTML = '我是新創建的節點';  
  5. document.body.appendChild(elem);  

 

通過 createElement 創建的元素並不屬於 document 對象,它只是創建出來,並未添加到html文檔中,要調用 appendChild 或 insertBefore 等方法將其添加到HTML文檔中。

createTextNode

創建文本節點: 

 
  1. var node = document.createTextNode("我是文本節點");  
  2. document.body.appendChild(node);  

 

 

cloneNode

克隆一個節點: node.cloneNode(true/false) ,它接收一個bool參數,用來表示是否復制子元素。

  1. var from = document.getElementById("test");  
  2. var clone = from.cloneNode(true);  
  3. clone.id = "test2";  
  4. document.body.appendChild(clone);  

 

 

克隆節點並不會克隆事件,除非事件是用 <div onclick="test()"></div> 這種方式綁定的,用 addEventListener 和 node.onclick=xxx; 方式綁定的都不會復制。

createDocumentFragment

本方法用來創建一個 DocumentFragment ,也就是文檔碎片,它表示一種輕量級的文檔,主要是用來存儲臨時節點,大量操作DOM時用它可以大大提升性能。

假設現有一題目,要求給ul添加10000個li,我們先用最簡單的拼接字符串的方式來實現:


  1. <ul id="ul"></ul>  
  2. <script>  
  3. (function()  
  4. {  
  5.     var start = Date.now();  
  6.     var str = '';  
  7.     for(var i=0; i<10000; i++)   
  8.     {  
  9.         str += '<li>第'+i+'個子節點</li>';  
  10.     }  
  11.     document.getElementById('ul').innerHTML = str;  
  12.     console.log('耗時:'+(Date.now()-start)+'毫秒'); // 44毫秒  
  13. })();  
  14. </script>  

 

 

再換逐個append的方式,不用說,這種方式效率肯定低:


  1. <ul id="ul"></ul>  
  2. <script>  
  3. (function()  
  4. {  
  5.     var start = Date.now();  
  6.     var str = '', li;  
  7.     var ul = document.getElementById('ul');  
  8.     for(var i=0; i<10000; i++)  
  9.     {  
  10.         li = document.createElement('li');  
  11.         li.textContent = '第'+i+'個子節點';  
  12.         ul.appendChild(li);  
  13.     }  
  14.     console.log('耗時:'+(Date.now()-start)+'毫秒'); // 82毫秒  
  15. })();  
  16. </script>  

 

 

最后再試試文檔碎片的方法,可以預見的是,這種方式肯定比第二種好很多,但是應該沒有第一種快:


  1. <ul id="ul"></ul>  
  2. <script>  
  3. (function()  
  4. {  
  5.     var start = Date.now();  
  6.     var str = '', li;  
  7.     var ul = document.getElementById('ul');  
  8.     var fragment = document.createDocumentFragment();  
  9.     for(var i=0; i<10000; i++)  
  10.     {  
  11.         li = document.createElement('li');  
  12.         li.textContent = '第'+i+'個子節點';  
  13.         fragment.appendChild(li);  
  14.     }  
  15.     ul.appendChild(fragment);  
  16.     console.log('耗時:'+(Date.now()-start)+'毫秒'); // 63毫秒  
  17. })();  
  18. </script>  

 

 

節點修改API

節點修改API都具有下面這幾個特點:

  1. 不管是新增還是替換節點,如果其原本就在頁面上,那么原來位置的節點將被移除;
  2. 修改之后節點本身綁定的事件不會消失;

appendChild

這個其實前面已經多次用到了,語法就是:

parent.appendChild(child);

它會將child追加到parent的子節點的最后面。另外,如果被添加的節點是一個頁面中存在的節點,則執行后這個節點將會添加到新的位置,其原本所在的位置將移除該節點,也就是說不會同時存在兩個該節點在頁面上,且其事件會保留。

insertBefore

將某個節點插入到另外一個節點的前面,語法:

  1. parentNode.insertBefore(newNode, refNode);  

 

這個API個人覺得設置的非常不合理,因為插入節點只需要知道newNode和refNode就可以了,parentNode是多余的,所以jQuery封裝的API就比較好:

  1. newNode.insertBefore(refNode); // 如 $("p").insertBefore("#foo");  

 

 

所以切記不要把這個原生API和jQuery的API使用方法搞混了!為了加深理解,這里寫一個簡單的例子:


  1. <div id="parent">  
  2.     我是父節點  
  3.     <div id="child">  
  4.         我是舊的子節點  
  5.     </div>  
  6. </div>  
  7. <input type="button" id="insertNode" value="插入節點" />  
  8. <script>  
  9. var parent = document.getElementById("parent");  
  10. var child = document.getElementById("child");  
  11. document.getElementById("insertNode").addEventListener('click', function()  
  12. {  
  13.     var newNode = document.createElement("div");  
  14.     newNode.textContent = "我是新節點";  
  15.     parent.insertBefore(newNode, child);  
  16. }, false);  
  17. </script>  

 

 

關於第二個參數:

  • refNode是必傳的,如果不傳該參數會報錯;
  • 如果refNode是undefined或null,則insertBefore會將節點添加到末尾;

removeChild

removeChild用於刪除指定的子節點並返回子節點,語法:

  1. var deletedChild = parent.removeChild(node);  

 

 

deletedChild指向被刪除節點的引用,它仍然存在於內存中,可以對其進行下一步操作。另外,如果被刪除的節點不是其子節點,則將會報錯。一般刪除節點都是這么刪的:

 
  1. function removeNode(node)  
  2. {  
  3.     if(!node) return;  
  4.     if(node.parentNode) node.parentNode.removeChild(node);  
  5. }  

 

 

replaceChild

replaceChild用於將一個節點替換另一個節點,語法:

 
  1. parent.replaceChild(newChild, oldChild);  

 

節點關系API

DOM中的節點相互之間存在着各種各樣的關系,如父子關系,兄弟關系等。

父關系API

  • parentNode :每個節點都有一個parentNode屬性,它表示元素的父節點。Element的父節點可能是Element,Document或DocumentFragment;
  • parentElement :返回元素的父元素節點,與parentNode的區別在於,其父節點必須是一個Element元素,如果不是,則返回null;

子關系API

  • children :返回一個實時的 HTMLCollection ,子節點都是Element,IE9以下瀏覽器不支持;
  • childNodes :返回一個實時的 NodeList ,表示元素的子節點列表,注意子節點可能包含文本節點、注釋節點等;
  • firstChild :返回第一個子節點,不存在返回null,與之相對應的還有一個 firstElementChild ;
  • lastChild :返回最后一個子節點,不存在返回null,與之相對應的還有一個 lastElementChild ;

兄弟關系型API

  • previousSibling :節點的前一個節點,如果不存在則返回null。注意有可能拿到的節點是文本節點或注釋節點,與預期的不符,要進行處理一下。
  • nextSibling :節點的后一個節點,如果不存在則返回null。注意有可能拿到的節點是文本節點,與預期的不符,要進行處理一下。
  • previousElementSibling :返回前一個元素節點,前一個節點必須是Element,注意IE9以下瀏覽器不支持。
  • nextElementSibling :返回后一個元素節點,后一個節點必須是Element,注意IE9以下瀏覽器不支持。

元素屬性型API

setAttribute

給元素設置屬性:


  1. element.setAttribute(name, value);  

 

 

其中name是特性名,value是特性值。如果元素不包含該特性,則會創建該特性並賦值。

getAttribute

getAttribute返回指定的特性名相應的特性值,如果不存在,則返回null:


  1. var value = element.getAttribute("id");  

 

樣式相關API

直接修改元素的樣式

  1. elem.style.color = 'red';  
  2. elem.style.setProperty('font-size', '16px');  
  3. elem.style.removeProperty('color');  

動態添加樣式規則 

 
  1. var style = document.createElement('style');  
  2. style.innerHTML = 'body{color:red} #top:hover{background-color: red;color: white;}';  
  3. document.head.appendChild(style);  

window.getComputedStyle

通過 element.sytle.xxx 只能獲取到內聯樣式,借助 window.getComputedStyle 可以獲取應用到元素上的所有樣式,IE8或更低版本不支持此方法。

  1. var style = window.getComputedStyle(element[, pseudoElt]);  

 

 

getBoundingClientRect

getBoundingClientRect 用來返回元素的大小以及相對於瀏覽器可視窗口的位置,用法如下:


  1. var clientRect = element.getBoundingClientRect();  

 

 

clientRect是一個 DOMRect 對象,包含width、height、left、top、right、bottom,它是相對於窗口頂部而不是文檔頂部,滾動頁面時它們的值是會發生變化的。

來源http://blog.csdn.net/hj7jay/article/details/53389522


免責聲明!

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



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