理解 DocumentFragment
含義:建立文件片段,它繼承了Node的所有方法,對DOM操作效能非常好。
建立文件片段 如下方法:
var frag = document.createDocumentFragment();
文件片段有三個node屬性,nodeType, nodeName, nodeValue; 他們的值分別是 11, '#document-fragment', null, 文件片段節點沒有父節點parentNode. 如下程式碼演示:
var frag = document.createDocumentFragment(); console.log(frag.nodeType); // 11 console.log(frag.nodeValue); // null console.log(frag.nodeName); // #document-fragment console.log(frag.parentNode); // null
它有什麼作用呢?
我們經常使用js來操作DOM操作,比如向頁面中插入元素,每次插入元素的時候,瀏覽器會發生重繪,都需要重新渲染頁面,如果做大量的這樣的操作,非常影響效能的,影響使用者體驗。
比如如下程式碼:
var ul = document.getElementById("ulId"); for (var i = 0; i < 30; i++) { var li = document.createElement('li'); li.innerHTML = "aaa" + i; ul.appendChild(li) }
我們知道每一次插入都會引起重新渲染(計算元素的尺寸,顯示內容等),會重新重繪頁面,因此會影響效能的,我們最常見還有一種方法是將建立的元素寫到一個字串上,然後一次性寫到innerHTML上,這種使用瀏覽器對innerHTML的解析比上面多次插入快很多,但是構造字串靈活性比較差,很難符合建立各種各樣的DOM元素。如下程式碼:
var ul = document.getElementById("ulId"); var ihtml = ''; for (var i = 0; i < 30; i++) { ihtml += '<li>'+i+'</li>'; } ul.innerHTML = ihtml;
但是使用DocumentFragment,可以彌補上面兩種方法的不足。
DocumentFragment是沒有父節點的最小文件物件,常用於儲存html和xml文件,它繼承了Node,因此它有Node的所有屬性和方法,完全可以操作Node那樣操作DocumentFragment.
DocumentFragment文件片段是存在於記憶體中的,沒有在DOM中,所以將子元素插入到文件片段中不會引起頁面迴流,因此使用DocumentFragment可以起到效能優化作用。
比如上面插入的程式碼可以改成如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport"> <meta content="yes" name="apple-mobile-web-app-capable"> <meta content="black" name="apple-mobile-web-app-status-bar-style"> <meta content="telephone=no" name="format-detection"> <meta content="email=no" name="format-detection"> <title>標題</title> <link rel="shortcut icon" href="/favicon.ico"> </head> <body> <ul id="ulId"></ul> <script> var ul = document.getElementById("ulId"); var frag = document.createDocumentFragment(); var ihtml = ''; for (var i = 0; i < 30; i++) { var li = document.createElement('li'); li.innerHTML = "index: " + i; frag.appendChild(li); } ul.appendChild(frag); </script> </body> </html>