patternjavascriptMinor
Implementing an algorithm that walks the DOM without recursion
Viewed 0 times
withouttherecursionalgorithmthatdomimplementingwalks
Problem
Here's a simple algorithm that walks the DOM given a node:
I wanted to implement it iteratively as an exercise, and came up with this:
I have used a couple tricks to make it behave the same way as the first recursive version. Is there a more concise way of writing this without recursion?
function walkDOM(n) {
do {
console.log(n);
if (n.hasChildNodes()) {
walkDOM(n.firstChild)
}
} while (n = n.nextSibling)
}I wanted to implement it iteratively as an exercise, and came up with this:
function walkDOM2(n) {
var recStack = [];
// First get the parent of the given node, so that
// you can get the siblings of the given node too
// (starting from the last sibling),
// rather than just start with the children of the
// given node.
// (This is to make this behave the
// same way as the recursive one.)
recStack.push(n.parentNode);
while (recStack.length > 0) {
var current = recStack.pop();
// Log only if the current node is
// the given node or a node below it.
// (This is to make this behave the
// same way as the recursive one.)
if (current != n.parentNode)
console.log(current);
if (!current.hasChildNodes())
continue;
current = current.lastChild;
do {
recStack.push(current);
// Skip the sibling nodes
// before the given node.
// (This is to make this behave the
// same way as the recursive one.)
if (current === n)
break;
} while (current = current && current.previousSibling);
}
}I have used a couple tricks to make it behave the same way as the first recursive version. Is there a more concise way of writing this without recursion?
Solution
I know you are doing this as an exercise, and personally I like the recursive function. But just as an alternative, there is also the much forgotten TreeWalker API.
Browser compatibility
Supported by IE9+, FF2+, Chrome 1+, Safari 3+, Opera 9+
Javascript
On jsfiddle
Browser compatibility
Supported by IE9+, FF2+, Chrome 1+, Safari 3+, Opera 9+
Javascript
var treeWalker = document.createTreeWalker(document.getElementById("list"), NodeFilter.SHOW_ALL, {
acceptNode: function (node) {
return NodeFilter.FILTER_ACCEPT;
}
}, false);
do {
console.log(treeWalker.currentNode);
} while (treeWalker.nextNode());On jsfiddle
Code Snippets
var treeWalker = document.createTreeWalker(document.getElementById("list"), NodeFilter.SHOW_ALL, {
acceptNode: function (node) {
return NodeFilter.FILTER_ACCEPT;
}
}, false);
do {
console.log(treeWalker.currentNode);
} while (treeWalker.nextNode());Context
StackExchange Code Review Q#28307, answer score: 9
Revisions (0)
No revisions yet.