在页面上将 JSON 数据显示为可展开/可折叠列表

Mil*_*caJ 8 javascript python tree json list

我需要有关在可展开/可折叠列表等页面上显示 JSON 数据的帮助。

这是我使用 Python 从 XML 转换的有效 JSON:

JSON 数据

为了显示它,我使用了这个:

<!DOCTYPE HTML>
<head>
    <title>JSON Tree View</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.min.js" type="text/javascript"></script>

</head>
<script>
function json_tree(object){
        var json="<ul>";
        for(prop in object){
            var value = object[prop];
            switch (typeof(value)){
                case "object":
                    var token = Math.random().toString(36).substr(2,16);
                    json += "<li><a class='label' href='#"+token+"' data-toggle='collapse'>"+prop+"="+value+"</a><div id='"+token+"' class='collapse'>"+json_tree(value)+"</div></li>";
                break;
                default:
                json += "<li>"+prop+"="+value+"</li>";
            }
        }
        return json+"</ul>";
}
</script>
<body style="margin: 40px;">
<h3>Paste JSON Into The Textarea Below and Click 'Build Tree'</h3>

<textarea id="json" style="width: 100%;min-height:300px;">

</textarea>
<button onclick="$('#output').html(json_tree(JSON.parse($('#json').val())));">Build Tree</button>
<div id="output">

</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

这就是我得到的:

图片

我需要帮助“填充”(或与上节点合并)那些“0”和“1”,以及 - 如何只显示没有名称的属性值(或者如果你有更好的想法我如何才能显示这个列表)?

vas*_*vas 8

一个好看的,小巧,可折叠树视图

pgrabovets'json-view非常干净,设计精良。

查看演示


Bil*_*bar 7

如果您可以考虑使用 JS 库,请考虑使用JSON FormatterRender JSON。这两个库都提供配置选项,如主题、最大深度和排序。要使用 Render JSON 以可折叠形式显示简单的 JSON 字符串,您可以使用

<script>
    document.getElementById("test").appendChild(
        renderjson({ hello: [1,2,3,4], there: { a:1, b:2, c:["hello", null] } })
    );
</script>
Run Code Online (Sandbox Code Playgroud)


Car*_*ard 7

某些问题的链接无法再访问。我假设您正在寻找如何制作可折叠的 JSON 视图。

\n
\n

长话短说

\n

您可以跳转到完整代码

\n

代码很短(200行\xe2\x86\x93,包括JSDoc、注释、测试代码。)

\n

启发您如何解决问题。

\n

这个问题在某些技巧上很像如何制作目录。(目录

\n
    \n
  1. 首先,JSON 数据就像一个对象。我们需要做的就是为每个项目添加更多属性(键、深度、子项……)。

    \n
  2. \n
  3. 完成这些操作后,剩下的就是渲染,这里是渲染的伪代码。

    \n
    render(node) {\n  const divFlag = document.createRange().createContextualFragment(`<div style="margin-left:${node.depth * 18}px"></div>`)\n  const divElem = divFlag.querySelector("div")\n  const spanFlag = document.createRange().createContextualFragment(\n    `<span class="ms-2">${node.key} : ${node.value}</span>`\n  )\n  node.children.forEach(subNode => {\n    const subElem = render(subNode)\n    spanFlag.append(subElem)\n  })\n  divElem.append(spanFlag)\n  return divElem\n}\n
    Run Code Online (Sandbox Code Playgroud)\n
  4. \n
\n

完整代码

\n

这两个 CSS 都不是必需的。

\n\n

\r\n
\r\n
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"\n      integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossOrigin="anonymous">\n<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css"\n      integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ=="\n      crossOrigin="anonymous" referrerpolicy="no-referrer"/>\n\n<script type="module">\n  //  main script {Node, Tree, JsonView}\n  class Node {\n    /**\n     * @description Add more attributes to the item.\n     * @param {*} item\n     * @param {*} key\n     * @param {Node} parent\n     * */\n    constructor(item, key, parent) {\n      this.key = key\n\n      /** @param {string} */\n      this.type = Array.isArray(item) ? "array" : typeof item\n\n      /** @param {Number} */\n      this.depth = parent ? parent.depth + 1 : 0\n      this.value = item\n      this.parent = parent\n\n      /** @param {[Node]} */\n      this.children = []\n    }\n  }\n\n  class Tree {\n    /**\n     * @description Given the root node, it will complete the children of it.\n     * @param {Node} rootNode\n     */\n    constructor(rootNode) {\n      this.root = rootNode\n\n      const obj = this.root.value\n      if (!(obj instanceof Object)) { // Array is an Object too.\n        return\n      }\n      Object.keys(obj).forEach(keyOrIdx => {\n        const value = obj[keyOrIdx]\n        const subNode = new Node(value, keyOrIdx, rootNode)\n        const subTree = new Tree(subNode)\n        rootNode.children.push(subTree.root)\n      })\n    }\n\n    /**\n     * @param {string | Object} jsonData\n     * @return {Tree}\n     */\n    static CreateTree(jsonData) {\n      jsonData = typeof jsonData === "string" ? JSON.parse(jsonData) : jsonData\n      const rootNode = new Node(jsonData, "root", null)\n      return new Tree(rootNode)\n    }\n  }\n\n  class JsonView {\n    static DefaultColorMap = {\n      text: {\n        string: "green",\n        number: "#f9ae58",\n        boolean: "#ca4ff8",\n        array: "black",\n        object: "black",\n      },\n      bg: {\n        object: undefined,\n        // ... You can add more by yourself. They are like the text as above.\n      }\n    }\n\n    static NewConfig() {\n      return JSON.parse(JSON.stringify(JsonView.DefaultColorMap))\n    }\n\n    static SEPARATOR = " : "\n\n    /** @type {Tree} */\n    #tree\n\n    /**\n     * @param {Tree} tree\n     * */\n    constructor(tree) {\n      this.#tree = tree\n    }\n\n    /**\n     * @param {Node} node\n     * @param {Object} colorMap\n     */\n    #render(node, colorMap = JsonView.DefaultColorMap) {\n      /**\n       * @param {Node} node\n       * */\n      const getValue = (node) => {\n        const typeName = node.type\n        switch (typeName) {\n          case "object":\n            return `object {${Object.keys(node.value).length}}`\n          case "array":\n            return `array [${Object.keys(node.value).length}]`\n          default:\n            return node.value\n        }\n      }\n\n      const arrowIcon = ["object", "array"].includes(node.type) ? `<i class="fas fa-caret-down"></i>` : ""\n      const divFlag = document.createRange().createContextualFragment(`<div style="margin-left:${node.depth * 18}px">${arrowIcon}</div>`)\n      const divElem = divFlag.querySelector("div")\n\n      const textColor = colorMap.text[node.type] !== undefined ? `color:${colorMap.text[node.type]}` : ""\n      const bgColor = colorMap.bg[node.type] !== undefined ? `background-color:${colorMap.bg[node.type]}` : ""\n      const valueStyle = (textColor + bgColor).length > 0 ? `style=${[textColor, bgColor].join(";")}` : ""\n\n      const keyName = node.depth !== 0 ? node.key + JsonView.SEPARATOR : "" // depth = 0 its key is "root" which is created by the system, so ignore it.\n      const spanFlag = document.createRange().createContextualFragment(\n        `<span class="ms-2">${keyName}<span ${valueStyle}>${getValue(node)}</span></span>`\n      )\n\n      const isCollapsible = ["object", "array"].includes(node.type)\n\n      node.children.forEach(subNode => {\n        const subElem = this.#render(subNode, colorMap)\n\n        if (isCollapsible) {\n          divFlag.querySelector(`i`).addEventListener("click", (e) => {\n            e.stopPropagation()\n            subElem.dataset.toggle = subElem.dataset.toggle === undefined ? "none" :\n              subElem.dataset.toggle === "none" ? "" : "none"\n\n            e.target.className = subElem.dataset.toggle === "none" ? "fas fa-caret-right" : "fas fa-caret-down" // Change the icon to \xe2\x96\xb6 or \xe2\x96\xbc\n\n            subElem.querySelectorAll(`*`).forEach(e => e.style.display = subElem.dataset.toggle)\n          })\n        }\n\n        spanFlag.append(subElem)\n      })\n      divElem.append(spanFlag)\n      return divElem\n    }\n\n    /**\n     * @param {Element} targetElem\n     * @param {?Object} colorMap\n     */\n    render(targetElem, colorMap = JsonView.DefaultColorMap) {\n      targetElem.append(this.#render(this.#tree.root, colorMap))\n    }\n  }\n\n  //  Below is Test\n  function main(outputElem) {\n    const testObj = {\n      db: {\n        port: 1234,\n        name: "My db",\n        tables: [\n          {id: 1, name: "table 1"},\n          {id: 2, name: "table 2"},\n        ],\n      },\n      options: {\n        debug: false,\n        ui: true,\n      },\n      person: [\n        "Foo", \n        "Bar"\n      ]\n    }\n    const tree = Tree.CreateTree(testObj)\n    const jsonView = new JsonView(tree)\n    jsonView.render(outputElem)\n    /* If you want to set the color by yourself, you can try as below\n    const config = JsonView.NewConfig()\n    config.bg.object = "red"\n    jsonView.render(outputElem, config)\n     */\n  }\n\n  (() => {\n    window.onload = () => {\n      main(document.body)\n    }\n  })()\n</script>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

普通 JavaScript

\n