使用递归从头开始实现 getElementByClassName
Implement getElementByClassName from scratch using recursion
我有提示构建一个函数,它是 getElementByClassName,使用 document.body
、element.classList
和 element.childNodes
AND 递归。
这就是我的 :
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 时,它会抛出错误。 “无法读取 属性 of classList of null”谈论第一个 if 语句。有什么想法吗?
我发现了一个不同的问题。您的数组并未返回 class 的所有实例,仅返回一个。我重新组织了您的 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
,它在特定元素 中找到具有给定 class 名称 的所有元素。然后我们在上面写 getElementsByClassName
,默认目标元素为 document.body
.
我们的 main 函数简单地测试当前元素以查看它是否具有正确的 class,如果是则将其放入单元素数组中,否则生成一个空数组,然后在任何 childNodes
, flatMap
将它们合并到一个数组中。
我有提示构建一个函数,它是 getElementByClassName,使用 document.body
、element.classList
和 element.childNodes
AND 递归。
这就是我的 :
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 时,它会抛出错误。 “无法读取 属性 of classList of null”谈论第一个 if 语句。有什么想法吗?
我发现了一个不同的问题。您的数组并未返回 class 的所有实例,仅返回一个。我重新组织了您的 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
,它在特定元素 中找到具有给定 class 名称 的所有元素。然后我们在上面写 getElementsByClassName
,默认目标元素为 document.body
.
我们的 main 函数简单地测试当前元素以查看它是否具有正确的 class,如果是则将其放入单元素数组中,否则生成一个空数组,然后在任何 childNodes
, flatMap
将它们合并到一个数组中。