So I am trying create a function, that will console.log the entire DOM tree of the HTML page. It is supposed to output the tag name of each HTML element in the order they appear - children before siblings + attribute name.
I have this working piece of code:
"use strict";
document.addEventListener("DOMContentLoaded", traverse);
function traverse() {
let elm = document.documentElement;
displayInfo(elm);
};
function displayInfo(elm){
//console.log(elm)
/* if (elm.childElementCount>0) {
let children = Array.from(elm.children);
console.log(children);
children.forEach( displayInfo );
}; */
if (elm.hasAttributes) {
//console.log(elm.attributes[0]);
};
var c = elm.childNodes;
let i;
for (i = 0; i < c.length; i++) {
console.log(c[i].nodeName);
if (c[i].childElementCount>0) {
//console.log(c[i].childElementCount);
if (c[i].hasAttributes) {
//console.log(c[i].attributes[0]);
};
let cc = c[i].children;
let ii;
for (ii=0; ii < cc.length; ii++) {
console.log(cc[ii].nodeName);
if (cc[ii].hasAttributes) {
//console.log(cc[ii].attributes[0]);
};
if (cc[ii].childElementCount>0) {
//console.log(cc[ii].childElementCount);
let ccc = cc[ii].children;
let iii;
for (iii=0; iii < ccc.length; iii++) {
console.log(ccc[iii].nodeName);
if (ccc[iii].hasAttributes) {
//console.log(ccc[iii].attributes[0]);
};
if (ccc[iii].childElementCount>0) {
//console.log(ccc[iii].childElementCount);
let cccc = ccc[iii].children;
let iiii;
for (iiii=0; iiii < cccc.length; iiii++) {
console.log(cccc[iiii].nodeName);
if (cccc[iiii].hasAttributes) {
//console.log(cccc[iiii].attributes[0]);
};
if (cccc[iiii].childElementCount>0) {
console.log(cccc[iiii].childElementCount)
}
}
}
}
}
}
}
}
};
The problem is, I am horribly repeating myself, plus I am manually setting how "deep" it will traverse. Is there a way to declare only one function that traverse?
PS: I know it's horrible to look at, I was just making sure the function would "work" all the way.
There is an API just for this which is way more powerful than anything you could try to build yourself: TreeWalker.
var walker = document.createTreeWalker(
document.documentElement,
NodeFilter.SHOW_ELEMENT // only elements
);
while (walker.nextNode()) {
let current = walker.currentNode;
console.log(
current.tagName,
[...current.attributes].map(({value,name}) => `${name}=${value}`).join()
);
}
<article>
<div id="container">container content
<span>one span</span>
<span class="nest1">nest1 span<span class="nest2">nest2 span</span></span>
</div>
</article>
Just wanted to add this simple log of all nodes in a document object element names id and classes included placed in a neat array.
console.log(document.getElementsByTagName('*'));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With