1. 程式人生 > 其它 >原生 JavaScript 的 DOM 操作彙總

原生 JavaScript 的 DOM 操作彙總

經常有人講在 IDE 中寫 C#、Java 會越來越手殘,那麼經常用 jQuery 也會讓我們忘記 JavaScript 是如何操作 DOM 的。 JavaScript的DOM操作也是面試中的常見問題,尤其是當你需要回答jQuery的效能問題時,便需要再次回到JavaScript DOM API。 本文便總結一下常見的 JavaScript DOM 操作方法,關於 JavaScript DOM 事件可以參考另一篇文章:DOM Level 2 Event 與 jQuery 原始碼:捕獲與冒泡

什麼是 DOM?

外行看來前端工程師的工作就是改頁面(HTML、CSS),寫指令碼(JavaScript)。當你意識到你不是在改HTML而是在操作DOM時,你就升級了! 那麼什麼是DOM?

MDN:文件物件模型 (DOM)是HTML和XML文件的程式設計介面。它提供了對文件的結構化的表述,並定義了一種方式可以使從程式中對該結構進行訪問,從而改變文件的結構,樣式和內容。DOM 將文件解析為一個由節點和物件(包含屬性和方法的物件)組成的結構集合。簡言之,它會將web頁面和指令碼或程式語言連線起來。

說白了 DOM 就是瀏覽器為 JavaScript 提供的一系列介面(通過window.documnet提供的),通過這些介面我們可以操作web頁面。但DOM並不是程式語言,它是文件物件的模型,該模型是獨立於程式語言的。比如我們在Python中也可以操作DOM:

import xml.dom.minidom as m
doc = m.parse("C:\\Projects\\Py\\chap1.xml");
doc.nodeName # DOM property of document object;
p_list = doc.getElementsByTagName("para");

所以Web前端常講的DOM API (web 或 XML 頁面) = DOM + JS (指令碼語言)

DOM 建立

DOM節點(Node)通常對應於一個標籤,一個文字,或者一個HTML屬性。DOM節點有一個nodeType屬性用來表示當前元素的型別,它是一個整數:

  1. Element,元素
  2. Attribute,屬性
  3. Text,文字

DOM節點建立最常用的便是document.createElementdocument.createTextNode方法:

var el1 = document.createElement('div');
var el2 = document.createElement('input');
var node = document.createTextNode('hello world!');

DOM 查詢

元素查詢的API返回的的結果是DOM節點或者DOM節點的列表。document提供了兩種Query方法:

// 返回當前文件中第一個類名為 "myclass" 的元素
var el = document.querySelector(".myclass");

// 返回一個文件中所有的class為"note"或者 "alert"的div元素
var els = document.querySelectorAll("div.note, div.alert");

// 獲取元素
var el = document.getElementById('xxx');
var els = document.getElementsByClassName('highlight');
var els = document.getElementsByTagName('td');

Element也提供了很多相對於元素的DOM導航方法:

// 獲取父元素、父節點
var parent = ele.parentElement;
var parent = ele.parentNode;

// 獲取子節點,子節點可以是任何一種節點,可以通過nodeType來判斷
var nodes = ele.children;    

// 查詢子元素
var els = ele.getElementsByTagName('td');
var els = ele.getElementsByClassName('highlight');

// 當前元素的第一個/最後一個子元素節點
var el = ele.firstElementChild;
var el = ele.lastElementChild;

// 下一個/上一個兄弟元素節點
var el = ele.nextElementSibling;
var el = ele.previousElementSibling;

DOM 更改

// 新增、刪除子元素
ele.appendChild(el);
ele.removeChild(el);

// 替換子元素
ele.replaceChild(el1, el2);

// 插入子元素
parentElement.insertBefore(newElement, referenceElement);

屬性操作

// 獲取一個{name, value}的陣列
var attrs = el.attributes;

// 獲取、設定屬性
var c = el.getAttribute('class');
el.setAttribute('class', 'highlight');

// 判斷、移除屬性
el.hasAttribute('class');
el.removeAttribute('class');

// 是否有屬性設定
el.hasAttributes();     

常見的面試問題

innerHTML 與 outerHTML 的區別?

DOM 元素的innerHTML,outerHTML,innerText,outerText屬性的區別也經常被面試官問到, 比如對於這樣一個HTML元素:<div>content<br/></div>

  • innerHTML:內部HTML,content<br/>
  • outerHTML:外部HTML,<div>content<br/></div>
  • innerText:內部文字,content
  • outerText:內部文字,content

上述四個屬性不僅可以讀取,還可以賦值。outerTextinnerText的區別在於outerText賦值時會把標籤一起賦值掉,另外xxText賦值時HTML特殊字元會被轉義。 下圖來源於:http://walsh.iteye.com/blog/261966

jQuery的html()與innerHTML的區別?

jQuery的.html()會呼叫.innerHTML來操作,但是會捕獲異常,然後用.empty(),.append()重新操作。 這是因為IE8中有些元素的.innerHTML是隻讀的。見:http://stackoverflow.com/questions/3563107/jquery-html-vs-innerhtml

本文采用知識共享署名 4.0 國際許可協議(CC-BY 4.0)進行許可,轉載註明來源即可:https://harttle.land/2015/10/01/javascript-dom-api.html。學識粗淺寫作倉促,如有錯誤辛苦評論或郵件指出。