我目前正致力于学习递归,并尝试通过使用递归遍历DOM来重新实现getElementsByClassName
函数。我终于觉得我已经掌握了这些概念,但是当我将匹配元素推入结果数组时,我遇到了问题。继承我的代码:
var getElementsByClassName = function(className){
var results = [];
var domWalker = function(node) {
for (var i=0; i<node.children.length; i++) {
if (node.children[i].classList.contains(className)) {
console.log(node.children[i])
results.push(node.children[i])
}
if (node.children[i].children.length > 0) {
domWalker(node.children[i])
}
}
return results;
};
domWalker(document.body);
console.log(results)
};
基本上,我需要结果数组来保存它以HTML格式找到的匹配元素,如下所示:
[<div class="title"></div>, <button class="click"></button>]
...当我将这些元素推送到我的结果数组中时,它们会更改为:[div.title, button.click]
格式。
我在console.log
的调用之上添加了results.push
语句,以查看结果是否以正确的格式显示,然后再将它们推送到数组中。推送到数组的结果是我正在寻找的结果,它们只是以错误的格式出现。
为什么push会导致我的结果格式发生变化?如何解决此问题?
答案 0 :(得分:0)
node.children [i]拥有对HTML元素的引用
console.log()应用隐含的.toString()方法给出你看到的内容。
你需要这个额外的代码(扩展到你找到的所有可能的tagNames):
var el = node.children[i];
el = '<' + el.tagName + (el.className ? ' class="' + el.className + '"': '') + '/>';
console.log(el);
results.push(el);
答案 1 :(得分:0)
我曾经解决过这个问题。虽然我还没有通读你的解决方案,但这是我的,有很多评论。我希望它有所帮助:
var getElementsByClassName = function(className, node){
// The empty results array, which gets created whenever the function is
// called.
var results = [];
// Default the node to the document's body if it isn't set. This way, we can
// call the function recursively with child elements, but never have to
// worry about it the first time around.
node = node || document.body;
// If the node contains the class list in question, let's push it into the
// results array.
if (node.classList && node.classList.contains(className)) {
results.push(node);
}
// Now, let's fetch the child nodes of the current node.
var children = node.childNodes;
// If child nodes exist, then we proceed here.
if (children) {
// Let's now loop over all child nodes of the current node in question. This
// way, we'll be able to perform checks on each child node.
for (var i = 0; i < children.length; i++) {
// Fetch the i child node.
var child = children[i];
// At this point, we want to pass the child node back into the function,
// implementing recursion. The same checks above will occur, and if the
// node has the class name, it will be added to the results array from
// that function call.
//
// This returns an array, and we need to merge it with the current set
// of results, so we concat it.
//
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat
results = results.concat(getElementsByClassName(className, child));
}
}
// We then return the combined results array from all the recursive function
// calls!
return results;
};