jQuery中的find()函数可以在给定的父元素中,获得当前父元素下指定的子元素集合。
关于find()的具体使用就不细说了,重点是如何使用原生JS来实现一样的功能。
当时想的方法是用递归来完成DOM树的遍历。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div class="carousel" id="id_carousel">
<ul class="img-ct">
<li id="0">
<a href="#">
<p>p0</p>
</a>
</li>
<li id="1">
<a href="#">
<p>p1</p>
</a>
</li>
</ul>
</div>
<script>
function findRecursion(parent, label) {
for (var i = 0; i < parent.children.length; i++) {
console.log(parent.children[i]);
findRecursion(parent.children[i], label);
}
}
/*
ul.img-ct {compact: false, type: "", title: "", lang: "", translate: true, …}
li#0 {value: 0, type: "", title: "", lang: "", translate: true, …}
a {target: "", download: "", ping: "", rel: "", relList: DOMTokenList(0), …}
p {align: "", title: "", lang: "", translate: true, dir: "", …}
li#1 {value: 0, type: "", title: "", lang: "", translate: true, …}
a {target: "", download: "", ping: "", rel: "", relList: DOMTokenList(0), …}
p {align: "", title: "", lang: "", translate: true, dir: "", …}
*/
</script>
</body>
</html>
其实自己对递归不是很熟练(科班出身学过算法的优势马上体现出来了有没有!),了解也不是很深刻,以至于当时写出来甚至都不知道如何运行的,后面一步一步打断点运行后才了解,也知道了为什么jQuery中find()
的源码没有使用这种方法来遍历DOM。
可以看到在调用堆栈中,有5个
findRecursion()
函数在堆栈内执行,此时遍历DOM深度是遍历到第一个li
元素内的p
元素上。由于p
本身没有后代元素(children.length=0
),不会再继续调用函数递归下去,执行栈弹出函数,i
自增......直到碰到下一个children.length>1
的元素,继续遍历下去。
实际上,节点中每存在一个后代节点,就会执行一次函数,如果元素节点很多很深,很容易造成栈溢出。
<ul class="img-ct">
<li id="0">
<a href="#">
<p>p0</p>
</a>
</li>
<li id="1">
<a href="#">
<p>p1</p>
</a>
</li>
</ul>
这是优化了一下函数,简单模拟了find()的功能。加入class、id、tagName
参数用于对比,数组用于保存符合功能的元素。
var result = [];
function findRecursion(parent,label) {
for (var i = 0; i < parent.children.length; i++) {
if (([].indexOf.call(parent.children[i].classList,label) !== -1) || parent.children[i].id === label || parent.children[i].tagName === label) {
result.push(parent.children[i]);
}
findRecursion(parent.children[i], label);
}
}
findRecursion(document.querySelectorAll(".carousel")[0],"P"); // Array(4) [p, p, p, p.p3]
console.log(result);
result = [];
findRecursion(document.querySelectorAll(".carousel")[0],"3"); // Array(1) [li#3]
console.log(result);
result = [];
findRecursion(document.querySelectorAll(".carousel")[0],"img-ct"); // Array(1) [ul.img-ct]
console.log(result);
result = [];
测试HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div class="carousel" id="id_carousel">
<ul class="img-ct">
<li id="0">
<a href="#"><p>p0</p></a>
</li>
<li id="1">
<a href="#"><p>p1</p></a>
</li>
<li id="2">
<a href="#"><p>p2</p></a>
</li>
<li id="3">
<a href="#"><p class="p3">p3</p></a>
</li>
</ul>
</div>
</body>
</html>
当然问题也有很多,如没有使用this,参数类型不严谨,每执行一次result数组要归0等等。
待更
网友评论