Reputation: 1477
Trying to hand-code getElementsByClassName
recursively.
While the code works in my console, I'm not passing my test case in mocha. Assuming the test case was written correctly, what can I do to make my code better (read: more correct)?
var getElementsByClassName = function(className){
var docBody = document.body;
var classes = [];
var walk = function (node, func) {
func(node);
node = node.firstChild;
while (node) {
walk(node, func);
node = node.sibling;
}
}
walk(docBody, function() {
if (docBody.classList.contains(className)) {
classes.push(docBody)
}
});
return classes;
};
Upvotes: 1
Views: 1542
Reputation: 14980
For a start, objects implementing the Element
interface have a nextSibling
(and a previousSibling
) property, not a sibling
property, so your while
loop always stops after the .firstChild
as the property access evaluates to a false-value.
Next time, please debug first.
Also, I recommend implementing this based on the return value of document.getElementsByTagName("*")
instead which already does the recursive traversal much more efficiently (since it uses native DOM code).
Your question sounds like a homework assignment. StackOverflow is there to help you solve real problems instead. Please read the FAQ on which questions are considered appropriate here.
Upvotes: 1
Reputation: 36458
Two problems, as noted above: node.sibling
should be node.nextSibling
, and you need to look at the node
passed to walk()
, not always at docBody
.
Additionally, some of the nodes you encounter (e.g. text nodes) won't have a classList
, so account for that:
var getElementsByClassName = function(className) {
var docBody = document.body;
var classes = [];
var walk = function (node, func) {
func(node);
node = node.firstChild;
while (node) {
walk(node, func);
node = node.nextSibling;
}
}
walk(docBody, function(node) {
if (node.classList && node.classList.contains(className)) {
classes.push(node)
}
});
return classes;
};
Upvotes: 4