我們用原生JS進行開發時,經常會用到兩種更新DOM節點的方法:innerHTML 和 appendChild() 。其中 innerHTML 會完全替換掉原先的節點內容,如果我們是想向元素追加子節點的話,那麼 innerHTML 顯然滿足不了需求。 轉而我們就會想到 appendChild() 方法。appendChild方法接收的引數型別為單個的節點型別物件。因此當我們要新增多個子節點時,只能通過迴圈來實現。
例如:
for (var i = Things.length - 1; i >= 0; i--) { element.appendChild(Things[i]); }
我們都知道,對DOM的操作次數越多,效能消耗也就越大。像這樣的迴圈新增節點,迴圈了多少次,就對DOM操作了多少次,效能消耗明顯是不划算的。我們就會想,能否把要插入的節點進行打包,然後一次性新增呢?如果可以的話,那就只對DOM做了一次操作了。要實現打包,這就要用到我們的主角 createDocumentFragment。
DocumentFragments是DOM節點。它們不是主DOM樹的一部分。通常的用例是建立文件片段,將元素附加到文件片段,然後將文件片段附加到DOM樹。在DOM樹中,文件片段被其所有的子元素所代替。因為文件片段存在於記憶體中,並不在DOM樹中,所以將子元素插入到文件片段時不會引起頁面迴流(對元素位置和幾何上的計算)。因此,使用文件片段通常會帶來更好的效能。
示例:建立主流web瀏覽器列表
HTML
<ul id="ul"></ul>
JAVASCRIPT
var element = document.getElementById(`ul`); var fragment = document.createDocumentFragment(); var browsers = [`Firefox`, `Chrome`, `Opera`, `Safari`, `Internet Explorer`]; browsers.forEach(function(browser) { var li = document.createElement(`li`); li.textContent = browser; fragment.appendChild(li); // 此處往文件片段插入子節點,不會引起迴流 (相當於打包操作) }); element.appendChild(fragment); // 將打包好的文件片段插入ul節點,只做了一次操作
參考資料: https://developer.mozilla.org/zh-CN/docs/Web/API/Document/createDocumentFragment