DOM笔记
1 var container=document.getElementById('list'); 2 for(var i=0;i<3;i++) 3 { 4 var item=document.createElement('li'); 5 item.innerText=i+1; 6 container.appendChild(item); 7 }
使用DOM需要注意点:
1.变量命名:节点类的变量,加上nd前缀更加容易辨识。
2.选择符命名:给CSS用和JS用的选择符分开,给JS用的选择符加上js-或J-前缀,提高可读性
3.容错能力:对节点的存在性做检查,保证代码更加健壮
4.最小作用域原则:应该将代码包在声明即执行的函数表达式里,不产生全局变量,也避免变量名冲突风险。
处理大量DOM事件的方法:
使用事件委托
1 var container=document.getElementById(js-'list'); 2 for(var i=0;i<300;i++) 3 { 4 var nditem=document.createElement('li'); 5 nditem.innerText=i+1; 6 ndcontainer.appendChild(nditem); 7 8 ndcontainer.addEvent('click',function(e){ 9 var target=e.target; 10 if (target.tagName==='LI'){ 11 alert(target.innerHTML); 12 } 13 }); 14 }
在每次循环中都会修改DOM结构,如果大循环执行时间过长,浏览器的渲染帧率过低将会导致卡顿,影响浏览效果。所以减少DOM操作次数、缩短循环时间可以坚持主线程阻塞的时间。
实用requestAnimationFrame以更加优化的方式,处理更大数量的DOM操作
1 (()=>{ 2 const ndContainer=document.getElementById('js-list'); 3 if (!ndContainer) { 4 return ; 5 } 6 const total=30000; 7 const batchSize=4; //每批插入的结点次数,越大渲染任务越繁重 8 const batchCount=total/batchSize; //需要处理多少次 9 let batchOne=0; //以完成处理的个数 10 11 function appendItem(){ 12 const fragment=document.createDocumentFragment(); 13 for(let i=0;i<batchSize;i++){ 14 const ndItem=document.createElement('li'); 15 ndItem.innerText=(batchDone*batchSize)+i+1; 16 fragment.appendChild(ndItem); 17 } 18 19 ndContainer.appendChild(fragment); 20 batchDone+=1; 21 doBatchAppend(); 22 } 23 24 function doBatchAppend(){ 25 if (batchDone<batchCount) { 26 window.requestAnimationFrame(appendItem); 27 } 28 } 29 30 doBatchAppend(); 31 32 ndContainer.addEventListener('click',function(e){ 33 const target=e.target; 34 if (target.tagName==='LI') { 35 alert(target.innerHTML); 36 } 37 }) 38 })();
DOM树的广度优先遍历:
1 const travers=(ndRoot)=>{ 2 const queue=[ndRoot]; 3 while(queue.length){ 4 const node=queue.shift(); 5 printInfo(node); 6 7 if (!node.children.length) { 8 continue; 9 } 10 Array.from(node.children).forEach(x=>queue.push(x)); 11 12 } 13 }; 14 15 const printInfo=(node)=>{ 16 console.log(node.tagName,'.${node.className}'); 17 }; 18 19 traverse(document.querySelector('.root'));
参考自:王仕军专栏