原生JavaScript DOM操做常見彙總

前言

最近在看JS性能優化方面,說到了createDocumentFragment()方法,對該方法有印象,但爲了進一步瞭解,我仍是從新查閱一遍,順便把DOM操做也給總結一下。javascript

建立新節點

  • createDocumentFragment()方法

該方法是用來建立一個虛擬的節點對象,或者說,是用來建立文檔碎片節點。它能夠包含各類類型的節點,在建立之初是空的。html

DocumentFragment 不是真實 DOM 樹的一部分,它的變化不會觸發 DOM 樹的從新渲染,且不會致使性能等問題。java

當把一個DocumentFragment節點插入文檔樹時,插入的不是DocumentFragment自身,而是它的全部子孫節點,即插入的是括號裏的節點。這個特性使得DocumentFragment成了佔位符,暫時存放那些一次插入文檔的節點。node

  • createElement()方法

在 HTML 文檔中,document.createElement() 方法用於建立一個由標籤名稱 tagName 指定的 HTML 元素性能優化

來看一個例子, 對於頁面已存在的<ul id="ul"></ul>元素,咱們想往裏面添加li標籤app

var ul = document.getElementById("ul");
for (var i = 0; i < 50; i++) {
    var li = document.createElement("li");
    li.innerHTML = "index: " + i;
    ul.appendChild(li);
}

上面操做看起來很正常,但實際要不少的插入操做和改動;而每一次的插入都會引發從新渲染,該操做會引起屢次渲染,在性能優化方面,有一點是減小DOM操做,由於DOM操做致使了頁面的重繪或重排。dom

  • createDocumentFragment()方法和createElement()方法區別

若是是用createDocumentFragment()方法操做性能

var ul = document.getElementById("ul");
var fragment = document.createDocumentFragment();
for (var i = 0; i < 50; i++) {
    var li = document.createElement("li");
    li.innerHTML = "index: " + i;
    fragment.appendChild(li);
}
ul.appendChild(fragment);

相比createElement()方法,此次是先將這些元素添加到fragment中,再統一將fragment添加到頁面,會減小頁面渲染dom的次數,效率會明顯提高。由於fragment文檔片斷存在於內存中,並不在DOM中,因此將子元素插入到文檔片斷中時不會引發頁面迴流(新建立的fragment片斷在文檔內是沒有對應的標籤的,這裏添加的是片斷的全部子節點)優化

  • createTextNode()方法

該方法會建立一個文本節點。code

HTML元素一般是由元素節點和文本節點組成。建立一個標題 (h1), 你必須建立 "h1" 元素和文本節點:

var h = document.createElement("h1")
var t = document.createTextNode("Hello World");
h.appendChild(t);

DOM更改:添加、移除、替換、插入

// 添加、刪除子元素
ele.appendChild(el);
ele.removeChild(el);

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

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

前面三個用法就一目瞭然,對於insertBefore()方法來舉個例子:

<ul id="ul">
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>
var newEle = document.createElement('li');
var textNode = document.createTextNode('insertNode');
newEle.appendChild(textNode);

var ul = document.getElementById('ul');
ul.insertBefore(newEle, ul.firstChild);

頁面輸出:

insertNode
1
2
3

DOM查詢

元素查詢的API返回的的結果是DOM節點或者DOM節點的列表

getElementById()  
getElementsByName()  
getElementsByTagName()
getElementsByClassName()
querySelector()
querySelectorAll()

querySelector() 方法返回匹配指定 CSS 選擇器元素的第一個子元素, 該方法只返回匹配指定選擇器的第一個元素。若是要返回全部匹配元素,須要使用 querySelectorAll() 方法替代.

document.querySelector("#test"); // 獲取到id名爲test的首個元素
  • querySelector系列方法與getElementBy系列方法對比
  1. 獲得的元素不是須要很麻煩的屢次getElementBy..的話,儘可能使用getElementBy系列方法,由於getElementBy系列執行速度更快。
  2. 獲得的元素須要很麻煩的屢次getElementBy...組合才能獲得的話使用querySelector,方便。
  3. querySelector()選擇的標籤是靜態的,也就是說在選中以後,可以一直保存,也就是脫離了被選擇的成爲副本。而getelementsBy系列方法是動態的,相互映射,在調用時,變化能夠及時的反映在頁面上。
// 用 querySelector 操做元素
var ul = document.querySelector('ul');
var list = ul.querySelectorAll('li');
for (var i = 0; i < 3; i++) { // 建立3個新的li標籤,添加到ul列表中
    ul.appendChild(document.createElement('li'));
}
console.log(list.length); // 3  
// 輸出的是添加前li的數量3,而非此時li的總數量6
var ul = document.getElementsByTagName('ul')[0];
var list = ul.getElementsByTagName('li');
for (var i = 0; i < 3; i++) { // 建立3個新的li標籤,添加到ul列表中
    ul.appendChild(document.createElement('li'));
}
console.log(list.length); // 6
  • 還有元素的DOM導航方法:
// 獲取父元素、父節點
var parent = ele.parentElement;
var parent = ele.parentNode;

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

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

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

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

屬性操做

getAttribute(key)
setAttribute(key,value)
hasAttribute(key)
removeAttribute(key)
相關文章
相關標籤/搜索