在 Javascript 中将 JSON 转换为 HTML
Posted
技术标签:
【中文标题】在 Javascript 中将 JSON 转换为 HTML【英文标题】:Convert JSON to HTML in Javascript 【发布时间】:2020-09-04 20:24:57 【问题描述】:我正在尝试使用 vanilla javascript 将 JSON 文件转换为 html。我接近它的方式似乎有效,但代码并不理想。
我正在做的是检查键的值是否是一个对象。如果是这样,这是一个新的 HTML 标记。如果不是,那么这是标签的属性。
我遇到的问题是我不知道如何在不复制代码的情况下正确循环对象并测试这些条件。
谁能帮我确定如何才能更好地写这个?
function createComponent(component, defaults, map)
Object.keys(defaults).forEach(function (level1)
if (typeof defaults[level1] === "object")
var tag = document.createElement(level1);
Object.keys(defaults[level1]).forEach(function (level2)
if (typeof defaults[level1][level2] === "object")
tag.appendChild(document.createElement(level2));
Object.keys(defaults[level1][level2]).forEach(function (level3)
if (typeof defaults[level1][level2][level3] === "object")
console.log(defaults[level1][level2][level3]);
tag.appendChild(document.createElement(level3));
);
);
);
createComponent("textBox", textBoxDefaults, map);
伪代码:
检查默认对象,这个级别有对象吗?如果是这样,请创建一个具有相同 Key 名称的 HTML 标记。是否存在不是对象的值?如果是这样,请使用键值对将属性添加到创建的标签。当您不再找到对象时,停止深入研究 JSON。
示例 JSON
textbox:
id: 1,
name: "Text Box",
tmprops:
cur: 0,
min: 5000,
visible: true,
,
tmctxlst:
version: "2",
txttmctx:
alwysshw: false,
name: "default"
,
期望的输出
<textbox id="1" name="text box">
<tmprops cur="0" min="5000" visible="true" />
<tmctxlst version="2">
<txttmctx alwysshow="false" name="default">
</tmctxlst>
</textbox>
【问题讨论】:
听起来你可以用递归函数来做到这一点......看看你是否可以使用递归重新实现它。此外,如果您可以编辑您的帖子以包含一些示例 JSON 和示例所需的输出,那就太棒了! 添加了示例 JSON 和所需的 HTML 输出 【参考方案1】:我相信这里避免代码重复的最简单方法是使用递归,它基本上可以如下所示:
function createObjectComponent(json)
const component = document.createElement("div");
for(const entry of Object.entries(json))
if(Array.isArray(value))
component.appendChild(createArrayComponent(value));
else if(typeof value === "object")
component.appendChild(createObjectComponent(value));
else
component.appendChild(createSimpleValueComponent(value));
return component
这是一个工作示例,带有一些较小的 css,它包括您自己的示例以及数组处理组件的示例:
const appDiv = document.getElementById('app');
const example1 =
foo: 1,
bar:
id: 2,
obj:
test: 2
,
a: ["a", "b", 1,
a: 1
]
const example2 =
id: 1,
name: "Text Box",
tmprops:
cur: 0,
min: 5000,
visible: true,
,
tmctxlst:
version: "2",
txttmctx:
alwysshw: false,
name: "default"
appDiv.appendChild(createObjectComponent(example2));
appDiv.appendChild(createObjectComponent(example1));
appDiv.appendChild(createArrayComponent(example1.a));
function createObjectComponent(json)
const component = document.createElement("div");
component.className = "obj-component";
component.innerHTML += "";
for (const entry of Object.entries(json))
component.appendChild(getComponentForEntry(entry));
component.innerHTML += "";
return component
function getComponentForEntry([key, value])
const entryDiv = document.createElement("div");
const keySpan = document.createElement("span");
keySpan.className = "key-span";
keySpan.innerText = key + ":";
entryDiv.appendChild(keySpan);
if (Array.isArray(value))
entryDiv.appendChild(createArrayComponent(value));
else if (typeof value === "object")
entryDiv.appendChild(createObjectComponent(value));
else
entryDiv.appendChild(createSimpleValueComponent(value));
return entryDiv;
function createArrayComponent(array)
const list = document.createElement("ul");
list.className = "array-component";
list.innerHTML += "[";
for (let i = 0; i < array.length; i++)
const item = array[i];
const listItem = document.createElement("li");
listItem.appendChild(getComponentForEntry([i, item]))
list.appendChild(listItem);
list.innerHTML += "]";
return list;
function createSimpleValueComponent(value)
const span = document.createElement("span");
span.innerText = value;
return span;
#app
font-family: monospace;
div.obj-component
margin: 8px;
background-color: #e4e4e4;
border-radius: 6px;
max-width: 300px;
padding: 4px 16px;
ul.array-component
margin: 8px;
background-color: #e4e4e4;
list-style-type: none;
padding: 4px 16px;
border-radius: 6px;
max-width: 300px;
span.key-span
padding-left: 16px;
margin-right: 8px;
color: blueviolet
span
color: green
<div id="app"></div>
【讨论】:
【参考方案2】:你需要一个递归来解决这个问题,
基本上我们将当前对象和它的键作为字符串,然后我们以dfs
方式遍历对象并创建适用的子对象,最后将标签返回到外部元素。
window.onload = function ()
console.log(solve(item.textbox, "textbox"));
const item =
textbox:
id: 1,
name: "Text Box",
tmprops:
cur: 0,
min: 5000,
visible: true,
,
tmctxlst:
version: "2",
txttmctx:
alwysshw: false,
name: "default"
,
function solve(obj, tagName)
const tag = document.createElement(tagName);
const currentKeys = Object.keys(obj)
currentKeys.forEach((attribute =>
if (typeof obj[attribute] === "object")
tag.appendChild(solve(obj[attribute], attribute))
else
tag.setAttribute(attribute, obj[attribute]);
))
return tag;
输出:
<textbox id="1" name="Text Box">
<tmprops cur="0" min="5000" visible="true"></tmprops>
<tmctxlst version="2">
<txttmctx alwysshw="false" name="default"></txttmctx>
</tmctxlst>
</textbox>
【讨论】:
这太棒了,非常感谢。如此简单而强大。以上是关于在 Javascript 中将 JSON 转换为 HTML的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Rails 中将 Javascript 对象转换为 JSON?
在 Javascript 中将 Map 转换为 JSON 对象
在Javascript中将JSON字符串转换为JSON对象数组