Mil*_*caJ 8 javascript python tree json list
我需要有关在可展开/可折叠列表等页面上显示 JSON 数据的帮助。
这是我使用 Python 从 XML 转换的有效 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”,以及 - 如何只显示没有名称的属性值(或者如果你有更好的想法我如何才能显示这个列表)?
如果您可以考虑使用 JS 库,请考虑使用JSON Formatter或Render 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)
某些问题的链接无法再访问。我假设您正在寻找如何制作可折叠的 JSON 视图。
\n您可以跳转到完整代码。
\n代码很短(200行\xe2\x86\x93,包括JSDoc、注释、测试代码。)
\n这个问题在某些技巧上很像如何制作目录。(目录)
\n首先,JSON 数据就像一个对象。我们需要做的就是为每个项目添加更多属性(键、深度、子项……)。
\n完成这些操作后,剩下的就是渲染,这里是渲染的伪代码。
\nrender(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}\nRun Code Online (Sandbox Code Playgroud)\n这两个 CSS 都不是必需的。
\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普通 JavaScript
\n