首页 > 代码库 > DOM笔记

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

参考自:王仕军专栏

 

DOM笔记