实现 DOM2JSON:将 DOM 节点转换为 JSON 格式
手写一个函数,将 DOM 树结构转换为 JSON 对象,保留节点的标签名、属性和子节点信息
问题
在前端开发中,有时需要将 DOM 节点序列化为 JSON 格式,以便于存储、传输或进行其他处理。这道题要求实现一个 DOM2JSON 函数,能够将一个 DOM 节点及其子节点转换为 JSON 对象,包含节点的标签名、属性和子节点等信息。
解答
/**
* 将 DOM 节点转换为 JSON 格式
* @param {HTMLElement} node - DOM 节点
* @returns {Object} JSON 对象
*/
function DOM2JSON(node) {
// 创建结果对象
const result = {};
// 1. 保存节点标签名
result.tag = node.tagName.toLowerCase();
// 2. 保存节点属性
if (node.attributes && node.attributes.length > 0) {
result.attributes = {};
Array.from(node.attributes).forEach(attr => {
result.attributes[attr.name] = attr.value;
});
}
// 3. 保存子节点
if (node.childNodes && node.childNodes.length > 0) {
result.children = [];
Array.from(node.childNodes).forEach(child => {
// 处理元素节点
if (child.nodeType === Node.ELEMENT_NODE) {
result.children.push(DOM2JSON(child));
}
// 处理文本节点(过滤空白文本)
else if (child.nodeType === Node.TEXT_NODE) {
const text = child.textContent.trim();
if (text) {
result.children.push({
type: 'text',
content: text
});
}
}
});
// 如果没有有效子节点,删除 children 属性
if (result.children.length === 0) {
delete result.children;
}
}
return result;
}
使用示例
// 示例 HTML 结构
const html = `
<div id="container" class="wrapper">
<h1>标题</h1>
<p class="text">这是一段文本</p>
<ul>
<li>列表项1</li>
<li>列表项2</li>
</ul>
</div>
`;
// 创建 DOM 节点
const container = document.createElement('div');
container.innerHTML = html;
const domNode = container.firstElementChild;
// 转换为 JSON
const json = DOM2JSON(domNode);
console.log(JSON.stringify(json, null, 2));
/* 输出结果:
{
"tag": "div",
"attributes": {
"id": "container",
"class": "wrapper"
},
"children": [
{
"tag": "h1",
"children": [
{
"type": "text",
"content": "标题"
}
]
},
{
"tag": "p",
"attributes": {
"class": "text"
},
"children": [
{
"type": "text",
"content": "这是一段文本"
}
]
},
{
"tag": "ul",
"children": [
{
"tag": "li",
"children": [
{
"type": "text",
"content": "列表项1"
}
]
},
{
"tag": "li",
"children": [
{
"type": "text",
"content": "列表项2"
}
]
}
]
}
]
}
*/
关键点
-
递归遍历:使用递归方式处理 DOM 树结构,确保所有层级的节点都能被正确转换
-
节点类型判断:需要区分元素节点(
ELEMENT_NODE)和文本节点(TEXT_NODE),分别进行处理 -
属性处理:通过
node.attributes获取所有属性,使用Array.from()转换为数组后遍历 -
文本节点过滤:使用
trim()过滤掉空白文本节点,避免 JSON 中出现无意义的空白内容 -
数据结构设计:合理设计 JSON 结构,包含
tag(标签名)、attributes(属性对象)、children(子节点数组)等字段 -
边界处理:当节点没有属性或子节点时,可以选择不添加对应字段,使 JSON 结构更简洁
-
可扩展性:可以根据需求扩展功能,如处理注释节点、保留样式信息等
目录