破解前端面试(80% 应聘者不及格系列):从 DOM 说起(转载)

破解前端面试(80% 应聘者不及格系列):从 DOM 说起


修改页面内容

要求:
页面上有个空的无序列表节点,用 <ul></ul> 表示,要往列表中插入 3 个 <li>,每个列表项的文本内容是列表项的插入顺序,取值 1, 2, 3,怎么用原生的 JS 实现这个需求?同时约定,为方便获取节点引用,可以根据需要为 <ul> 节点加上 id 或者 class 属性。
我的做法是
html

<ul id="list"></ul>

js

var ul = document.getElementById('list');
for(var i = 0; i < 3; i++) {
    var li = document.createElement('li');
    var text = document.createTextNode(i+1);
    li.appendChild(text);
    ul.appendChild(li);
}

我的解法正是该文章中的第一类解法,还有下面一种方式。

var ul = document.getElementById('list');
var lis = [];
for(var i = 0; i < 3; i++) {
    var li = '<li>'+(i+1)+'</li>';
    lis.push(li);
}
ul.innerHTML = lis.join('');

但这上面两个答案都不是最好的,对文章里提出的几点,进行改进。

//包含在声明即执行
{() => {
    //给节点类变量加上‘nd’
    var ndul = document.getElementById('list');
    //对节点进行检查,提高容错性
    if(!ndul) {
        return;
    }
    for(var i = 0; i < 3; i++) {
        var ndli = document.createElement('li');
        var ndtext = document.createTextNode(i+1);
        ndli.appendChild(ndtext);
        ndul.appendChild(ndli);
    }
})();

添加响应事件

要求:
现在页面上有了内容,接下来添加交互。问题:要当每个 <li> 被单击的时候 alert 里面的内容,该怎么做?
我的做法是:

var ul = document.getElementById('list');
for(var i = 0; i < 3; i++) {
    var li = document.createElement('li');
    var text = document.createTextNode(i+1);
    li.appendChild(text);
    //在此处添加一个监听事件
    li.addEventListener('click', function(e){
        alert(this.innerText);
    })
    ul.appendChild(li);
}  

插入的数据量变大后

如果要插入的 <li> 是 100 个,该怎么解决?
我的做法是

var ul = document.getElementById('list');
for(var i = 0; i < 100; i++) {
    var li = document.createElement('li');
    var text = document.createTextNode(i+1);
    li.appendChild(text);
    //不要在此处设置li的监听函数了,这样将会监听100个类似的监听函数
    ul.appendChild(li);
}  
//使用事件委托机制,即将监听事件绑定在ul上,使用e.target确定点击目标
ul.addEventListener('click', function(e){
    alert(e.target.innerText);
});

DOM树的遍历

深度优先搜索,使用递归即可

//deep_search
function deepSearch(node) {
    print(node);
    for(var i = 0; i < node.children.length; i++) {
        deepSearch(node.children[i]);
    }
}
function print(node) {
    console.log(node.tagName, node.className);
}
deepSearch(document.querySelector('.root'));

广度优先搜索

//wide_search
function wideSearch(root) {
    const queue = [root];
    print(root);
    while(queue.length != 0) {
        var node = queue.shift();
        if(node.children.length == 0) {
            continue;
        }
        for(var i = 0; i < node.children.length; i++) {
            queue.push(node.children[i]);
        }
    }
}
wideSearch(document.querySelector('.root'));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章