Javascript的DOM操作 - 你真的瞭解嗎?

摘要 想稍微系統的說說對於DOM的操作,把Javascript和jQuery常用操作DOM的內容歸納成思維導圖方便閱讀,同時加入性能上的一些問題.

    前言

    在前端開發的過程中,javascript極爲重要的一個功能就是對DOM對象的操作,無論增刪改查在前端頁面操作這一範圍內都是比較消耗性能的.如何高效率的,便捷的操作DOM,這就是本文要講述的.希望看完全文,你能知道如何更高效的通過原生js以及jQuery操作DOM元素.

    操作DOM

    這裏我希望介紹的相對系統一點,而不是東一句西一句,所以把Javascript和jQuery常用操作DOM的內容歸納成思維導圖方便閱讀.這裏就總結出最基本最常用的DOM操作.

    Javascript:


    jQuery:

    上面的思維導圖分別是javascript和jQuery下操作DOM的一些常用Function,並不完全我僅僅列出相對常用的.這裏我比較推薦的是jQuery的操作方式,更加便捷的同時在性能上也相對有所保障.

    性能影響

    DOM操作會導致最重要的,也是我們最需要的問題就是導致用戶阻塞的重構(reflow)和重繪(repaint).比較通俗的一句話就是你在頁面上的任何操作都是有代價的,有些大有些小,如果我們的操作比較頻繁或者波及範圍較大,那麼就要講究方式和技巧.reflow和repaint就是我們在改變頁面或者說操作DOM時,會帶來的兩種後果.

    reflow意味着結構的改變,比如一堆元素堆疊,改變其中一個的寬高,那麼相應的所有元素的位置都要改變.repaint意味着樣式的改變比如div調整了背景色等,但是位置不變,只改變我們操作的元素.所以通常來看repaint的代價要遠小於reflow,速度也更快.

    影響性能的因素我們已經知道了,那麼下面看一下怎麼避免.

    更有效的操作

    最重要的觀點:既然任何DOM操作都有代價,那麼最好就是不操作或者最少的操作DOM.所以首先記住一個原則,將DOM操作儘量少!這裏有我認爲主要的4個原則,記下來足以應付大多數情況.

    (1) 能放到DOM操作之外的操作就放到外面,DOM操作要儘量少.

    DOM操作優化中這一觀點在網上已經很普及了,很多例子都有比如遍歷一個數組然後逐漸把內容添加到DOM上,這裏就推薦先遍歷完數組,然後一次性在DOM上操作.大家可以看代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 不好的做法
for (var i=0; i < items.length; i++){
    var item = document.createElement("li");
    item.appendChild(document.createTextNode("Option " + i);
    list.appendChild(item);
}  
 
 
// 更好的做法
// 使用容器存放臨時變更, 最後再一次性更新DOM
var fragment = document.createDocumentFragment();
for (var i=0; i < items.length; i++){
    var item = document.createElement("li");
    item.appendChild(document.createTextNode("Option " + i);
    fragment.appendChild(item);
}
list.appendChild(fragment);

    (2) 大範圍操作先把容器隱藏,在其中操作完成後,再顯示.

    這是一個我剛接觸前端時遇到的一個優化辦法,當時很不理解爲什麼display=none之後操作就算是性能優化了.但是數據證明如此渲染確實快了很多,這個的原理要涉及到瀏覽器加載和渲染的原理,簡單說就是隱藏的元素其中不會產生reflow.這個例子我就不寫了,很簡單.

    (3) 樣式操作不要注意修改屬性,直接替換class

    這個還是比較容易理解的,你逐一修改要訪問很多次,而替換class就相當於批量操作了,訪問一次DOM就可以了,當然性能提高了.

    (4) 用變量保存DOM對象而不是多次獲取,同時減少操作DOM屬性的次數.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//不好
 
function addAnchor(parentElement, anchorText, anchorClass) {
  var element = document.createElement('a');
  parentElement.appendChild(element);
  element.innerHTML = anchorText;
  element.className = anchorClass;
}
 
 
//更好
 
function addAnchor(parentElement, anchorText, anchorClass) {
  var element = document.createElement('a');
  element.innerHTML = anchorText;
  element.className = anchorClass;
  parentElement.appendChild(element);
}

    總結

    說到這裏DOM的操作就差不多了,其實沒有什麼太新鮮的內容只是做了一個系統點總結.對於性能這部分要平時積累這個意識,因爲大多數時候它在開發過程中體現的並不明顯.本文還有很多不足,希望大家留言溝通吧.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章