從簡單的需求/面試題談起
自定義一個方法去檢查DOM中某個ID的元素。類似getElementById.
先推薦閱讀下:
廣度優先.
// HTML結構如下
<div class="wrapper">
<section class="header">
<div class="logo"></div>
</section>
<section class="main">
<div class="sidebar">
<ul class="menu">
<li class='li'>
<a href="" id='demo'>li1-a</a>
</li>
<li class='li'>
<a href="">li2</a>
</li>
</ul>
</div>
</section>
<section class="footer">
<div class="copyright"></div>
</section>
</div>
複製程式碼
簡單畫了下DOM節點(只考慮元素節點)圖:
程式碼實現
- 深度優先, 遞迴實現
const cusGetElementByIdByDFS = function (parentNode, id) {
// 深度優先, 遞迴實現
if (parentNode) {
let target = null;
const children = Array.from(parentNode.children);
if (parentNode.id === id) {
return parentNode;
}
for (let i = 0; i < children.length; i++) {
target = cusGetElementByIdByDFS(children[i], id);
if (target) {
return target;
}
}
}
return null;
}
複製程式碼
// 測試程式碼
console.log(cusGetElementByIdByDFS(document.querySelector('.wrapper') , 'demo'))
複製程式碼
- 深度優先, 非遞迴實現, 使用棧
const cusGetElementByIdByDFS2 = function (parentNode, id) {
if (!parentNode) {
return null;
}
// 深度優先, 非遞迴實現, 使用棧
let stack = [];
if (parentNode.id === id) {
return parentNode;
}
for (let i = parentNode.children.length; i > 0; i--) {
stack.push(parentNode.children[i - 1]);
}
while (stack.length) {
let node = stack.pop();
if (node.id === id) {
return node;
} else {
if (node.children.length > 0) {
stack = Array.from(node.children).concat(stack);
}
}
}
}
複製程式碼
// 測試程式碼
console.log(cusGetElementByIdByDFS2(document.querySelector('.wrapper') , 'demo'))
複製程式碼
- 廣度優先 非遞迴實現
const cusGetElementByIdByBFS = function (parentNode, id) {
// 廣度優先 非遞迴實現
// 佇列的思想: 採用出隊的方式遍歷節點,如果遍歷到的節點有子節點,則將子節點入隊
const layer = []; // 按照順序存放每個層級的每個節點
if (parentNode) {
// 初始化layer
// 節點深度從父節點開始算起
layer.push({
node: parentNode,
depth: 1
});
while (layer.length > 0) {
const root = layer.shift(); // 出隊
if (root.node.id === id) {
return root; // 包括對應節點和節點深度
} else {
if (root.node.children.length > 0) {
Array.from(root.node.children).forEach(node => {
layer.push({
node,
depth: root.depth + 1
})
})
}
}
}
}
return null;
}
複製程式碼
// 測試程式碼
console.log(cusGetElementByIdByBFS(document.querySelector('.wrapper') , 'demo'))
複製程式碼
後續看細下演算法書再做補充, 初次學習有勘誤請指出。