破解前端面試(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'));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章