js格式化json树结构

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>tree_json</title>
    <link rel="stylesheet" href="/static/css/normalize.css">
    <link rel="stylesheet" href="/static/css/zui.min.css">
    <link rel="stylesheet" href="/static/css/zui.base.css">
    <style>
        body {
            background: #fff;
            --y: 10px;
            --x: calc(var(--y) * 2);
            --p: calc(var(--y) / 4);
            --z: calc(var(--y) * 2 + var(--p) * 2);
            --yy: calc(var(--z) / 2);

        }

        .top {
            background: #fff;
            height: calc(var(--z));
            line-height: calc(var(--x));
            padding: calc(var(--p));
        }

        .top ul {
            list-style: none;
            margin: 0;
            padding: 0;
        }

        .top ul li {
            display: inline-flex;
        }

        .my-tree-menu {
            padding-left: 0;
            margin-left: calc(0px - var(--z) + var(--y) + var(--p) + 1px);
            margin-bottom: 0;
            background: #fff;
            border-top: 1px solid #ddd;
        }

        .my-tree-menu ul {
            padding-left: calc(var(--z));
        }

        .my-tree-menu, .my-tree-menu li, .my-tree-menu summary {
            list-style: none;
        }

        .my-tree-menu summary, .my-tree-menu li, .my-tree-menu a {
            position: relative;

        }

        .my-tree-menu summary {
            cursor: pointer;
        }

        .my-tree-menu summary::before {
            content: '+';
            display: block;
            position: absolute;
            top: 0;
            left: calc(0px - var(--z));
            width: calc(var(--x));
            height: calc(var(--x));
            line-height: calc(var(--x) - var(--p) - 2px);
            margin: calc(var(--p));

            background: #fff;
            border: 1px solid #ddd;
            color: #ddd;
            text-align: center;
            z-index: 998;
            border-radius: 50%;
        }

        .my-tree-menu details[open] > summary::before {
            content: '-';
        }

        .my-tree-menu li a::after {
            content: '';
            display: block;
            position: absolute;
            top: 0;
            left: calc(0px - var(--z));
            width: calc(var(--x));
            height: calc(var(--x));
            line-height: calc(var(--x));
            margin: calc(var(--p));
            background: #fff;
            border: 1px solid #ddd;
            color: #ddd;
            text-align: center;
            z-index: 998;
            border-radius: 50%;

        }


        .my-tree-menu ul li {
            border-left: 1px solid #ddd;
        }

        .my-tree-menu ul li::before {
            content: '';
            display: block;
            position: absolute;
            top: calc(0px - var(--yy) + 1px);;
            left: -1px;
            width: calc(var(--z));
            height: calc(var(--z));
            line-height: calc(var(--z));
            border: solid;
            border-width: 0 0 1px 1px;
            color: #ddd;
            text-align: center;
            z-index: 2;
        }

        .my-tree-menu ul {
            margin-left: calc(0px - var(--z) - var(--yy));
        }

        .my-tree-menu ul li:last-child {
            border-color: transparent;
        }

        .my-tree-menu li {
            padding-left: calc(var(--z) + var(--yy));
        }

        .my-tree-menu a {
            text-decoration: none;
            cursor: auto;
        }

        .my-tree-menu a:focus {
            outline: none;
        }

        .my-tree-menu .inner {
            display: block;
            height: calc(var(--z));
            line-height: calc(var(--x));
            padding: calc(var(--p));
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            color: #333;
            padding-left: 500px;
            margin-left: -500px;
            position: relative;
            z-index: 999;
            cursor: auto;
        }

        .my-tree-menu .inner:hover {
            background: rgba(0, 0, 0, 0.1);
        }

        .my-tree-menu .active a::after {
            border-color: rgb(0, 123, 255);
            background: rgb(0, 123, 255);
        }

        .my-tree-menu .active .inner {
            color: rgb(0, 123, 255);
        }

        .iframe {
            background: #fff;
            width: 100%;
            height: auto;
            min-height: 900px;
            border: unset;
            border-left: 1px solid #ddd;
            border-top: 1px solid #ddd;
        }

        .my-row .col {
            padding: 0;
        }

        .end {
            border-top: 1px solid #ddd;
        }
    </style>
</head>
<body>
<div class="container-fluid">
    <div class="row my-row">
        <div class="col col-12">
            <div class="top">
                <ul>
                    <li class="logo"><a href="/">etafutre-json树结构</a></li>
                    <li><a href="javascript:;" onclick="location.reload()">刷新</a></li>
                </ul>
            </div>
        </div>
        <div class="col col-md-12 col-12" id="right">
            <textarea class="form-control" id="in" cols="30" rows="5"></textarea>
            <input type="submit" value="生成树结构" class="btn btn-primary" onclick="treeFormat()">
            <input type="submit" value="展开全部" class="btn" onclick="treeOpen(this)">
        </div>
        <div class="col col-md-12 col-12">
            <div id="my-tree-menu"></div>
        </div>

        <div class="col col-12">
            <div class="end"></div>
        </div>
    </div>

</div>
<script>
    document.addEventListener('DOMContentLoaded', function () {

    });
    function treeOpen(btn) {
        if(btn.value==='展开全部'){
            btn.value='折叠全部';
            document.getElementById('my-tree-menu').querySelectorAll('details').forEach(function (item) {
                item.open=true;
            });
        }else{
            btn.value='展开全部';
            document.getElementById('my-tree-menu').querySelectorAll('details[open]').forEach(function (item) {
                item.open=false;
            });
        }
    }
    function treeFormat() {
        const json_data = document.getElementById('in').value;
        if(json_data==='')
            return;
        let data =false;
        try{
            data = JSON.parse(json_data);
        }catch (e) {
            console.log(e);
        }
        if(data===false)
            return;
        if(!typeof data==="object")
            return;
        let lis = tree(data);
        let ul = '<ul id="my-tree-menu" class="my-tree-menu">' + lis + '</ul>';
        document.getElementById("my-tree-menu").innerHTML = ul;
    }

    function tree(data,key='',n=0) {
        let li = '';
        if (typeof data === "object") {
            if(n===0){
                li += '<li><details open><summary><span class="inner">'+key+'</span></summary><ul>';

            }else{
                li += '<li><details><summary><span class="inner">'+key+'</span></summary><ul>';

            }
            Object.keys(data).forEach(key => {
                if(data[key]===null)
                    data[key] = '';
                li += tree(data[key],key,1);
            });
            li += '</ul></details></li>';
        } else {
            if(typeof data==='string')
                li += '<li><a><span class="inner">' +key+': \''+data+ '\'</span></a></li>';
            else
                li += '<li><a><span class="inner">' +key+': '+data+ '</span></a></li>';
        }
        return li;
    }

</script>
</body>
</html>
相关推荐
Hello_Pyhx3 天前
NWinfo 导出 Windows 硬件信息:从 JSON 报告到缺项排查
windows·json
程序员大阳3 天前
副队长JavaScript教程(66)-本地存储实战:待办事项网页的开发
javascript·json·实战·待办事项·本地存储·案例
视觉小萌新4 天前
AI Class 3 · Chapter 2-3:函数、异常、文件读写+JSON / JSONL 读写(小白版)
人工智能·python·json
翊众建站5 天前
用 JSON-LD 给企业官网做结构化数据:LocalBusiness 与 FAQPage 实践笔记
人工智能·搜索引擎·json
Patrick_Wilson5 天前
读懂一个 Go JSON 处理函数:从输入数据追踪结构体、校验与错误返回
go·json·编程语言
January12076 天前
【AI方法笔记】2026-11-02:模型流式吐 JSON 时,前端会遇到四种崩法
前端·人工智能·笔记·json
Frag0ut7 天前
Notepad++ 零基础入门:从记事本到代码编辑器的平滑过渡(2026最新版)
python·编辑器·html·json·notepad++·markdown·记事本
xiaoye-duck8 天前
《C++ 工具库实战》C++ 解析利器 JsonCpp:从基础使用到封装简易 JSON 工具
c++·json·第三方库
javachen__8 天前
试试Jackson:把JSON拉平成普通属性
json