1. 程式人生 > >原生JS的DOM操作彙總

原生JS的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特殊字元會被轉義。

jQuery的html()與innerHTML的區別?

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