使用递归从头开始实现getElementByClassName



我有一个使用document.bodyelement.classListelement.childNodesand递归构建getElementByClassName函数的提示。这就是我所拥有的:

var getElementsByClassName = function(className
) {
var classNameArray = [];
var bodyElement = document.body;
var traverseTheNode = function(elementNode) {
if (elementNode.classList.contains(className)) {
classNameArray.push(elementNode);
}
elementNode.childNodes.forEach(function(node) {
if (node.classList === undefined) {
return;
} else if (node.classList.contains(className)) {
classNameArray.push(node);
} else {
return traverseTheNode(node);
}
});
}
};
console.log(getElementsByClassName('targetClassName'))

代码执行我希望它执行的操作,但当我console.log时,它会抛出一个错误"无法读取null"的classList的属性;谈论第一个if语句。有什么想法吗?

我发现了一个不同的问题。您的数组没有返回一个类的所有实例,只有一个实例。我重新组织了if语句,使其在其他条件之前遍历一个节点的子节点,现在似乎正在返回所有匹配的节点。

var getElementsByClassName = function(className) {
var classNameArray = [];
var bodyElement = document.body;
var traverseTheNode = function(elementNode) {
if (elementNode.classList.contains(className)) {
classNameArray.push(elementNode);
}
elementNode.childNodes.forEach(function(node) {
if (node.hasChildNodes()) {
return traverseTheNode(node);
} else if (node.classList === undefined) {
return;
} else if (node.classList.contains(className)) {
classNameArray.push(node);
}

});
}
traverseTheNode(bodyElement);
//console.log(classNameArray)
return classNameArray;
};
console.log(getElementsByClassName('three'))
<div class='three'>
<ul class="two">
<li>Hmmm
<dd class='three'>
</dd>
</li>
</ul>
</div>

这将上述内容转化为更实用的样式:

const gebcn = (className) => (element) => 
(Array .from (element .classList || []) .includes (className)
? [element] 
: []
).concat (
element .hasChildNodes() 
? Array .from (element .childNodes) .flatMap (gebcn (className))
: []
)

const getElementsByClassName = (className) => gebcn (className) (document .body)
console.log (getElementsByClassName ('three'))
<div class='three'>
<ul class="two">
<li>Hmmm
<dd class='three'>
</dd>
</li>
</ul>
</div>

我们编写了一个更通用的版本gebcn,它在特定元素中查找具有给定类名的所有元素。然后,我们在此基础上编写getElementsByClassName,将目标元素默认为document.body

我们的主函数只是测试当前元素,看看它是否有正确的类,如果有,就把它放在一个单一元素数组中,否则就产生一个空数组,然后在任何childNodesflatMap上递归,将它们ping成一个单一数组。

最新更新