一、返回值
1、静态的
querySelectorAll 的返回值是静态的,也就是通过js代码去动态创建节点时,querySelectorAll 的值不会更新
2、动态的
getElementsByTagName的返回值是动态的,到dom节点增加或者减少,getElementsByTagName能同步变化
3、代码说明
<ul>
<li>Lisa</li>
<li>Jennie</li>
<li>Rose</li>
<li>Jisoo</li>
</ul>
const ul1 = document.getElementsByTagName('ul');
const ul2 = document.querySelectorAll('ul')
ul1[0].appendChild(document.createElement('li'));
ul2[0].appendChild(document.createElement('li'));
console.log(li1.length); // 6
console.log(li2.length); // 4
二、查询时间
思考💡:getElementsByTagName 比querySelectorAll 快?
因为querySelectorAll 类似于去克隆整个dom树,getElementsByTagName 类似于对象的索引,随着dom节点越来越庞大,克隆总是没有通过索引的方式快
三、深度优先遍历
1、描述
一条路走到黑,不撞南墙不回头
深度优先遍历从某一个路径的起始点开始追溯直到遍历到这个路径的最后一个节点,然后回溯,从下一条路径继续开始,知道遍历完所有节点,如下图所示。
2、代码
//dom结构
<div class="root">
<div class="container">
<section class="sidebar">
<ul class="menu">
<li>
<a href=""></a>
</li>
<li>
<a href=""></a>
</li>
</ul>
</section>
<section class="main">
<article class="paragraph"></article>
<p class="note"></p>
</section>
</div>
</div>
//算法
const DFS = function (node) {
// node不存在
if (!node) {
return
}
// 深度
let deep = arguments[1] || 1
console.log(`${node.nodeName}.${node.classList} ${deep}`);
//递归结束条件
if (!node.children.length) {
return
}
// 数组化,然后依次DFS
Array.from(node.children).forEach((item) => {
DFS(item, deep + 1);
})
}
DFS(document.body.querySelector('.root'))
四、广度优先遍历
1、描述
学海无涯
先遍历同一层次邻近的节点,然后再往下一层遍历,如图所示
2、代码
const BFS = function (root) {
// node不存在
if (!root) {
return
}
let queue = [{ item: root, depth: 1 }]
// 队不空
while (queue.length) {
//出队
let node = queue.shift();
console.log(`${node.item.nodeName}.${node.item.classList} ${node.depth}`);
if (!node.item.children.length) {
continue;
}
Array.from(node.item.children).forEach((item) => {
queue.push({
item: item,
depth: node.depth + 1
})
})
}
}
BFS(document.body.querySelector('.root'))