日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

加速Javascript:DOM操作优化

發布時間:2024/8/22 java 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 加速Javascript:DOM操作优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文:《Speeding up JavaScript: Working with the DOM》

作者: KeeKim Heng, Google Web Developer

?

在我們開發互聯網富應用(RIA)時,我們經常寫一些javascript腳本來修改或者增加頁面元素,這些工作最終是DOM——或者說文檔對象模 型——來完成的,而我們的實現方式會影響到應用的響應速度。

DOM操作會導致瀏覽器重解析(reflow),這是瀏覽器的一個決定頁面元素如何展現的計算過程。直接修改DOM,修改元素的CSS樣式,修改瀏 覽器的窗口大小,都會觸發重解析。讀取元素的布局屬性比如offsetHeithe或者offsetWidth也會觸發重解析。重解析需要花費計算時間, 因此重解析觸發的越少,應用就會越快。

DOM操作通常要不就是修改已經存在的頁面上的元素,要不就是創建新的頁面元素。下面的4種優化方案覆蓋了修改和創建DOM節點兩種方式,幫助你減 少觸發瀏覽器重解析的次數。

方案一:通過CSS類名切換來修改DOM?

這個方案讓我們可以一次性修改一個元素和它的子元素的多個樣式屬性而只觸發一次重解析。

需求:

我們現在需要寫一個函數來修改一個超鏈接的幾個樣式規則。要實現很簡單,把這幾個規則對應的屬性逐一改了就好了。但是帶來的問題是,每修改一個樣式 屬性,都會導致一次頁面的重解析。

function?selectAnchor(element)?{
??element.style.fontWeight?
=?'bold';
??element.style.textDecoration?
=?'none';
??element.style.color?
=?'#000';
}

?

解決方案

要解決這個問題,我們可以先創建一個樣式名,并且把要修改的樣式規則都放到這個類名上,然后我們給超鏈接添加上這個新類名,就可以實現添加幾個樣式 規則而只觸發一次重解析了。這個模式還有個好處是也實現了表現和邏輯相分離。

?

.selectedAnchor?{
??font
-weight:?bold;
??text
-decoration:?none;
??color:?#
000;
}

?

function?selectAnchor(element)?{
??element.className?
=?'selectedAnchor';
}


方案二:在非渲染區修改DOM

上一個方案解決的是修改一個超鏈接的問題,當一次需要對很多個超鏈接進行相同修改的時候,這個方案就可以大顯身手了。

需求

需求是這樣的,我們要寫一個函數來修改一個指定元素的子元素中所有的超鏈接的樣式名(className)屬性。要實現很簡單,我們可以通過遍歷每 個超鏈接并且修改它們的樣式名來完成任務。但是帶來的問題就是,每修改一個超鏈接都會導致一次重解析。

function?updateAllAnchors(element,?anchorClass)?{
??
var?anchors?=?element.getElementsByTagName('a');
??
for?(var?i?=?0,?length?=?anchors.length;?i?<?length;?i?++)?{
????anchors[i].className?
=?anchorClass;
??}
}

解決方案

要解決這個問題,我們可以把被修改的指定元素從DOM里面移除,再修改所有的超鏈接,然后在把這個元素插入回到它原來的位置上。為了完成這個復雜的 操作,我們可以先寫一個可重用的函數,它不但移除了這個DOM節點,還返回了一個把元素插回到原來的位置的函數。

/**
?*?Remove?an?element?and?provide?a?function?that?inserts?it?into?its?original?position
?*?@param?element?{Element}?The?element?to?be?temporarily?removed
?*?@return?{Function}?A?function?that?inserts?the?element?into?its?original?position
?*
*/
function?removeToInsertLater(element)?{
??
var?parentNode?=?element.parentNode;
??
var?nextSibling?=?element.nextSibling;
??parentNode.removeChild(element);
??
return?function()?{
????
if?(nextSibling)?{
??????parentNode.insertBefore(element,?nextSibling);
????}?
else?{
??????parentNode.appendChild(element);
????}
??};
}

有了上面這個函數,現在我們就可以在一個不需要解析渲染的元素上面修改那些超鏈接了。這樣只在移除和插入元素的時候各觸發一次重解析。


function?updateAllAnchors(element,?anchorClass)?{
??
var?insertFunction?=?removeToInsertLater(element);
??
var?anchors?=?element.getElementsByTagName('a');
??
for?(var?i?=?0,?length?=?anchors.length;?i?<?length;?i?++)?{
????anchors[i].className?
=?anchorClass;
??}
??insertFunction();
}

方案三:一次性的DOM元素生成

這個方案讓我們創建一個元素的過程只觸發一次重解析。在創建完元素以后,先進行所有需要的修改,最后才把它插入到DOM里面去就可以了

需求

需求是這樣的,實現一個函數,往一個指定的父元素上插入一個超鏈接元素。這個函數要同時可以設置這個超鏈接的顯示文字和樣式類。我們可以這樣做:創 建元素,插入到DOM里面,然后設置相應的屬性。這就要觸發3次重解析。

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);
}

不過,要是我們想要插入很多個超鏈接到一個元素里面的話,那么這個做法還是有問題:每插入一個超鏈接還是要觸發一次重解析。下一個方案可以解決這個 問題。

方案四:通過文檔片段對象(DocumentFragment)創建一組元素

這個方案允許我們創建并插入很多個元素而只觸發一次重解析。要實現這點需要用到所謂的文檔片段對象(DocumentFragment)。我們先在 DOM之外創建一個文檔片段對象(這樣它也就不需要解析和渲染),然后我們在文檔片段對象中創建很多個元素,最后我們把這個文檔片段對象中所有的元素一次 性放到DOM里面去,只觸發一次重解析。

需求


我們要寫一個函數,往一個指定的元素上面增加10個超鏈接。如果我們簡單的直接插入10個超鏈接到元素上面,就會觸發10次重解析。

function?addAnchors(element)?{
??
var?anchor;
??
for?(var?i?=?0;?i?<?10;?i?++)?{
????anchor?
=?document.createElement('a');
????anchor.innerHTML?
=?'test';
????element.appendChild(anchor);
??}
}

解決方案

要解決這個問題,我們要先創建一個文檔片段對象,然后把每個新創建的超鏈接都插入到它里面去。當我們把文檔片段對象用appendChild命令插 入到指定的節點時,這個文檔片段對象的所有子節點就一起被插入到指定的元素里面,而且只需要觸發一次重解析。

function?addAnchors(element)?{
??
var?anchor,?fragment?=?document.createDocumentFragment();
??
for?(var?i?=?0;?i?<?10;?i?++)?{
????anchor?
=?document.createElement('a');
????anchor.innerHTML?
=?'test';
????fragment.appendChild(anchor);
??}
??element.appendChild(fragment);
}

轉載于:https://www.cnblogs.com/MaxIE/archive/2010/03/11/1683501.html

總結

以上是生活随笔為你收集整理的加速Javascript:DOM操作优化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。