【问题标题】:Turning nested JSON into an HTML nested list with Javascript使用 Javascript 将嵌套 JSON 转换为 HTML 嵌套列表
【发布时间】:2010-11-15 18:06:44
【问题描述】:

我对使用 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 的类,那也很棒。

非常感谢任何帮助。

谢谢,

戴夫。

【问题讨论】:

  • FWIW:我认为您的 JSON 有问题。有几个地方在同一个对象中有多个“节点”键。

标签: javascript json list nested


【解决方案1】:

您可以自己浏览您的 json 结构并在需要时创建适当的<li>,但我建议您实现复合模式。详情请见link

【讨论】:

    【解决方案2】:

    您的 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>
    

    See it in action.

    【讨论】:

      【解决方案3】:

      这里有一些相当简单的代码,它为每个对象创建一个&lt;ul&gt; 元素,并为每个部分创建一个&lt;li&gt; 元素。如果您想添加特殊情况,您可以添加快速检查以测试 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 中的对象都是映射,因此您不能有多个具有相同名称的子对象。正如 Cédric 指出的那样,您需要将多个“节点”转换为一个数组。

      【讨论】:

        猜你喜欢
        • 2013-03-17
        • 1970-01-01
        • 1970-01-01
        • 2020-09-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-13
        • 2020-03-21
        相关资源
        最近更新 更多