Превращение вложенного JSON во вложенный список HTML с помощью Javascript
-
06-07-2019 - |
Вопрос
Я новичок в использовании JSON (в отличие от XML) и в настоящее время работаю исключительно с Javascript, чтобы переваривать, анализировать и отображать возвращаемые данные JSON.
Я использую библиотеку JSON2.js и получаю некоторые действительные данные JSON, представляющие довольно простой вложенный список:
{
"node":{
"class":"folder",
"title":"Test Framework",
"node":{
"class":"folder",
"title":"Item 1",
"node":{
"class":"folder",
"title":"Item 1.1",
"node":{
"class":"file",
"title":"Item 1.1.a"
}
},
"node":{
"class":"folder",
"title":"Item 1.2",
"node":{
"class":"file",
"title":"Item 1.2.a"
},
"node":{
"class":"file",
"title":"Item 1.2.b"
},
"node":{
"class":"file",
"title":"Item 1.2.c"
}
},
"node":{
"class":"folder",
"title":"Item 1.3",
"node":{
"class":"folder",
"title":"Item 1.3.a",
"node":{
"class":"file",
"title":"Item 1.3.a.i"
},
"node":{
"class":"file",
"title":"Item 1.3.a.ii"
}
}
}
},
"node":{
"class":"folder",
"title":"Item 2",
"node":{
"class":"file",
"title":"item 2.a"
},
"node":{
"class":"file",
"title":"Item 2.b"
}
}
}
}
Есть ли у кого-нибудь подсказки, как быстро превратить этот участок в UL со всеми вложенными элементами?Было бы также здорово, если бы элемент «класс» в JSON можно было использовать в качестве класса для каждого LI.
Буду признателен за любую оказанную помощь.
Спасибо,
Дэйв.
Решение
Ваш json не подходит для вашей задачи.Некоторые объекты имеют несколько свойств с одинаковым именем («узел»), поэтому они переопределяют друг друга.Вместо этого вам придется использовать массивы узлов.Вот рабочая структура данных и функции, которые могут превратить ее во вложенный список:
<!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<script type="text/javascript">
function parseNodes(nodes) { // takes a nodes array and turns it into a <ol>
var ol = document.createElement("OL");
for(var i=0; i<nodes.length; i++) {
ol.appendChild(parseNode(nodes[i]));
}
return ol;
}
function parseNode(node) { // takes a node object and turns it into a <li>
var li = document.createElement("LI");
li.innerHTML = node.title;
li.className = node.class;
if(node.nodes) li.appendChild(parseNodes(node.nodes));
return li;
}
window.jsonData = [{
"class": "folder",
"title": "Test Framework",
"nodes": [{
"class": "folder",
"title": "Item 1",
"nodes": [{
"class": "folder",
"title": "Item 1.1",
"nodes": [{
"class": "file",
"title": "Item 1.1.a"
}]
},
{
"class": "folder",
"title": "Item 1.2",
"nodes": [{
"class": "file",
"title": "Item 1.2.a"
},
{
"class": "file",
"title": "Item 1.2.b"
},
{
"class": "file",
"title": "Item 1.2.c"
}]
},
{
"class": "folder",
"title": "Item 1.3",
"nodes": [{
"class": "folder",
"title": "Item 1.3.a",
"nodes": [{
"class": "file",
"title": "Item 1.3.a.i"
},
{
"class": "file",
"title": "Item 1.3.a.ii"
}]
}]
}]
},
{
"class": "folder",
"title": "Item 2",
"nodes": [{
"class": "file",
"title": "item 2.a"
},
{
"class": "file",
"title": "Item 2.b"
}]
}]
}];
</script>
</head>
<body>
<input type="button"
onclick="document.body.appendChild(parseNodes(jsonData))"
value="go" />
</body>
</html>
И я могу добавить этот CSS, чтобы нумерация элементов соответствовала названиям узлов :)
<style type="text/css">
ol { list-style-type: none }
ol ol { list-style-type: decimal }
ol ol ol { list-style-type: decimal }
ol ol ol ol { list-style-type: lower-alpha }
ol ol ol ol ol { list-style-type: lower-roman }
</style>
Другие советы
Вот довольно простой код, который создает <ul>
элемент для каждого объекта и <li>
элемент для каждой порции.Вы можете добавить быструю проверку для проверки child
переменная против таких вещей, как "class"
если вы хотите добавить особый случай.
function jsonToHtmlList(json) {
return objToHtmlList(JSON.parse(json));
}
function objToHtmlList(obj) {
if (obj instanceof Array) {
var ol = document.createElement('ol');
for (var child in obj) {
var li = document.createElement('li');
li.appendChild(objToHtmlList(obj[child]));
ol.appendChild(li);
}
return ol;
}
else if (obj instanceof Object && !(obj instanceof String)) {
var ul = document.createElement('ul');
for (var child in obj) {
var li = document.createElement('li');
li.appendChild(document.createTextNode(child + ": "));
li.appendChild(objToHtmlList(obj[child]));
ul.appendChild(li);
}
return ul;
}
else {
return document.createTextNode(obj);
}
}
Это не даст именно того, что вы хотите, потому что ваш JSON не имеет смысла.Объекты в JavaScript и, следовательно, JSON являются картами, поэтому у вас не может быть более одного дочернего элемента с одним и тем же именем.Как указывает Седрик, вам нужно будет превратить несколько «узлов» в массив.
Вы можете самостоятельно просмотреть структуру json и создать соответствующие <li>
при необходимости, но я предлагаю вам реализовать составной шаблон.Видеть связь Больше подробностей