当你需要对dom元素进行一系列操作时,可以通过以下步骤来减少重绘和重排的次数。
- 使元素脱离文档流;
- 对其应用多重改变;
- 把元素带回文档中;
该过程会触发两次重排 - 第一步和第三部。如果你忽略这两个步骤,那么第二步所产生的任何修改都会触发一次重排。
有三种方式可以使DOM脱离文档流:
- 隐藏元素,应用修改,重新显示。
- 使用文档片段在DOM之外构建一个子树,再把它拷贝回文档。
- 将原始元素拷贝到一个脱离文档的节点中,修改副本,完成后再替换原始元素。
<ul id="myList"> <li><a href="1.jpg">图片一</a></li> <li><a href="2.jpg">图片二</a></li> </ul> var data = [{ url: '1.jpg', name: "图片一" },{ url: "2.jpg", name: "图片二" }]通用部分:
function el(dom,data) { var oA,oLi; for(var i=0,len=data.length;i<len;i++) { oLi = document.createElement('li'); oA = document.createElement('a'); oA.href = data[i].url; oA.appendChild(document.createTextNode(data[i].name)) ; oLi.appendChild(oA); dom.appendChild(oLi) } }不考虑重排:
var myList = document.getElementById('myList');
el(myList,data)
method 1: 通过改变display属性,临时从文档中移除<ul>元素,然后再回复它。
myList.display = 'none'; el(myList,data) myList.display = 'block';method 2:在文档之外创建病更新一个文档片段,然后把它附加到原始列表中
var myList = document.getElementById('myList'); var fragment = document.createDocumentFragment(); el(fragment,data) myList.appendChild(fragment)method 3: 为修改的节点创建一个备份,然后对副本进行操作,一旦操作完成,就用新的节点替换旧的节点。
var old = document.getElementById('myList'); var clone = old.cloneNode(true); el(clone,data) old.parentNode.replaceChild(clone,old)