var WTDom = function() {
var results = {};
return {
init: function() {
// Usage: WTDom.wRecursiveTest(document.body, 4) for traversing a complete binary tree of depth 4
// Alternatively you can paste any html content inside <body><div id="start"></div></body>
// and comment out the setUp function.
},
// cleans the DOM and create a complete binary tree of level n
setUp: function(level) {
document.body.innerHTML = '';
var rootN = document.createElement('div');
rootN.className = 'start';
document.body.appendChild(rootN);
this.createTree(document.body.firstChild, level);
},
wRecursiveTest: function(node, level) {
this.setUp(level);
var recursiveProfile = this.setProfile();
this.wRecursive(node, function(w) { w.className = 'testClass'; });
var recursiveTime = this.stopProfile(recursiveProfile);
console.log(recursiveTime);
},
wIterativeTest: function(node, level) {
this.setUp(level);
var iterativeProfile = this.setProfile();
this.wIterative(node, function(w) { w.className = 'testClass'; });
var iterativeTime = this.stopProfile(iterativeProfile);
console.log(iterativeTime);
},
setProfile: function() {
return new Date().getTime();
},
stopProfile: function(startTime) {
return new Date().getTime() - startTime;
},
// from Crockford's “Theory of the DOM”
wRecursive: function(node, func) {
func(node);
node = node.firstChild;
while (node) {
this.wRecursive(node, func);
node = node.nextSibling;
}
},
// the iterative alternative
wIterative: function(node, func) {
var rootback = false;
var rootnode = node;
func(node);
node = node.firstChild;
while (!rootback) {
func(node);
if (node.firstChild != null) node = node.firstChild;
else if (node.nextSibling != null) node = node.nextSibling;
else {
while (node.parentNode.nextSibling == null && node != rootnode && node.parentNode.firstChild != rootnode) {
node = node.parentNode;
}
if (node.parentNode.nextSibling != null) node = node.parentNode.nextSibling;
else rootback = true;
}
}
},
createTree: function(node, height, complete) {
if (height > 0) {
height -= 1;
var child = document.createElement('div');
var sibling = document.createElement('div');
child.className = 'child';
sibling.className = 'sibling';
node.appendChild(child);
node.parentNode.appendChild(sibling);
this.createTree(node.firstChild, height);
this.createTree(node.nextSibling, height);
}
},
// level-order traversing
viewTree: function(root, func) {
var node = '';
var oldk = null;
var k = 0;
var c = 2;
var q = [];
q.push(root);
while (q.length != 0) {
node = q.splice(0,1)[0]; // first-in first-out
func(node)
k = Math.floor(Math.log(c) / Math.LN2); // assuming a perfect binary tree
if (k != oldk) {
oldk = k;
console.log("Level "+oldk+":"+k+":"+c);
}
c += 1;
if (node.firstChild != null) q.push(node.firstChild);
if (node.nextSibling != null) q.push(node.nextSibling);
}
}
}
}();