admin管理员组文章数量:1352803
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.
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.
Share Improve this question asked May 12, 2018 at 10:30 the_odorthe_odor 551 silver badge8 bronze badges 2-
Rather than
if (condition) { big block }
, you canif (!condition) continue;
to reduce indentation hell. – CertainPerformance Commented May 12, 2018 at 10:31 - And how would that look like in the example? I am sorry I am still not entirely familiar with the if statements – the_odor Commented May 12, 2018 at 10:34
3 Answers
Reset to default 4There 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('*'));
Note that hasAttributes
is a function, not a property. element.hasAttributes
will always be true
.
Use recursion, like this:
function displayInfo(node) {
console.log(node.nodeName);
if (node.nodeType === 3) {
console.log('Text node: ' + node.textContent);
return;
}
if (node.hasAttributes()) {
[...node.attributes].forEach(({ name, value }) => console.log(`${name}=${value}`));
}
node.childNodes.forEach(displayInfo);
}
displayInfo(document.documentElement);
<article>
<div id="container">container content
<span>one span</span>
<span class="nest1">nest1 span<span class="nest2">nest2 span</span></span>
</div>
</article>
The continue
shortcut I mentioned would look like this, to start with:
for (i = 0; i < c.length; i++) {
console.log(c[i].nodeName);
if (c[i].childElementCount === 0) continue;
//console.log(c[i].childElementCount);
if (c[i].hasAttributes) {
//console.log(c[i].attributes[0]);
};
let cc = c[i].children;
Avoid indentation when you can - you'll make your code a lot more readable.
本文标签: javascriptHow to consolelog entire HTML DOM tree in order with attribute namesStack Overflow
版权声明:本文标题:javascript - How to console.log entire HTML DOM tree in order with attribute names - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1743914223a2560931.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论