<ul class="menu">
<li>Top_1
<ul>
<li>Sub_1</li>
<li>Sub_2</li>
<li>Sub_3
<ul>
<li>Sub_sub_1</li>
<li>Sub_sub_2</li>
</ul>
</li>
</ul>
</li>
<li>Top_2
<ul>
<li>Sub_1</li>
<li>Sub_2</li>
<li>Sub_3
<ul>
<li>Sub_sub_1</li>
<li>Sub_sub_2</li>
</ul>
</li>
</ul>
</li>
</ul>
function toJSON(node) {
node = node || this;
var obj = {
nodeType: node.nodeType
};
if (node.tagName) {
obj.tagName = node.tagName.toLowerCase();
} else
if (node.nodeName) {
obj.nodeName = node.nodeName;
}
if (node.nodeValue) {
obj.nodeValue = node.nodeValue;
}
var attrs = node.attributes;
if (attrs) {
var length = attrs.length;
var arr = obj.attributes = new Array(length);
for (var i = 0; i < length; i++) {
attr = attrs[i];
arr[i] = [attr.nodeName, attr.nodeValue];
}
}
var childNodes = node.childNodes;
if (childNodes) {
length = childNodes.length;
arr = obj.childNodes = new Array(length);
for (i = 0; i < length; i++) {
arr[i] = toJSON(childNodes[i]);
}
}
return obj;
}
console.log(toJSON(document.querySelector('.menu')))
const nodeToObj = node => ({
type: node.nodeType,
value: node.nodeValue,
tag: node.tagName,
childNodes: Array.from(node.childNodes, nodeToObj),
attributes: node.attributes && Array.from(
node.attributes,
({ name, value }) => ({ name, value })
),
});
const nodeToJSON = (node, ...args) =>
JSON.stringify(nodeToObj(node), ...args);
const json = nodeToJSON(document.querySelector('.menu'), null, 2);
document.body.insertAdjacentHTML('beforeend', `<pre>${json}</pre>`);