[jquery]关于ajax+json,根据id pid生成树形结构

时间:2021-10-23 12:01:38

之前也练习过生成树的小功能,不过json结构不一样,这里做个记录.

新的写法受到了ajax请求json数据案例 的很大启发,非常感谢.话不多说,直接贴代码,

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>测试json:id pid产生树</title>
    <style>

    </style>
</head>

<body>
    <div id="container">
    </div>
    <script src="http://code.jquery.com/jquery-1.8.3.js"></script>
    <script>
    var menulist = ""; //存放整个节点信息
    $(document).ready(function() {
        ///////////////////////////////////////////////////////////直接用数组
        // var menuArray = [
        //     { "id": 1, "pid": 0, "text": "1,pid0" },
        //     { "id": 2, "pid": 1, "text": "2,pid1" },
        //     { "id": 3, "pid": 1, "text": "3,pid1" },
        //     { "id": 4, "pid": 3, "text": "4,pid3" },
        //     { "id": 5, "pid": 0, "text": "5,pid0" }
        // ];
        // console.log(menuArray);
        // GetTree(0, menuArray);
        // $("#container").append(menulist);
        // $("#container ul li").find("li").toggle(); //第一层直接显示
        // $("p").click(function() {
        //     $(this).next().children("li").toggle();
        //     return false;
        // });
        ///////////////////////////////////////////////////////////使用ajax
        var menuArray = new Array();
        $.ajax({
            url: "tree.json",
            data: {},
            type: "POST",
            dataType: "JSON",
            //请使用火狐浏览器
            success: function(data) {
                for (var i in data) {
                    if ('treeInfo' == i) { //json文件中treeInfo区域内容
                        for (var j = 0; j < data[i].length; j++) {
                            menuArray.push(data[i][j]);
                        }
                        console.log(menuArray);
                    }
                }
                // 成功组成数组,开始生成树,这一段不能写在外面复用,因为ajax是异步的,先后顺序不确定
                GetTree(0, menuArray);
                $("#container").append(menulist);
                $("#container ul li").find("li").toggle(); //第一层直接显示
                $("p").click(function() {
                    $(this).next().children("li").toggle();
                    return false;
                });
                ////生成完毕
            },
            error: function() {
                alert('请求失败,请检查网络');
            }
        });
        /////////.reday结束
    });
    //获取树,实际节点从1开始,0作为初始
    function GetTree(id, array) {
        var childArray = GetChildArray(id, array);
        // console.log(childArray);
        if (childArray.length > 0) { //存在下属子节点
            menulist += '<ul>';
            for (var i in childArray) {
                menulist += '<li><p>' + childArray[i].text + '</p>';
                GetTree(childArray[i].id, array); //递归
                menulist += '</li>';
                //<ul> <li><p>text</p><子节点.....></li><兄弟节点...></ul>
            }
            menulist += '</ul>';
        }
    }
    //返回某个节点的子节点列表
    function GetChildArray(id, array) {
        var newArray = new Array();
        for (var i in array) {
            if (array[i].pid == id) //有节点指向此节点
                newArray.push(array[i]);
        }
        return newArray;
    }
    </script>
</body>

</html>

jquery为了方便调用的网络上的而非本地的.

json文件比较简单,只是为了演示一下基本结构,名称为tree.json并与html文件同级,内容如下:

{"treeInfo": [
    {"id": 1,"pid": 0,"text": "1,pid0"},
    {"id": 2,"pid": 1,"text": "2,pid1"},
    {"id": 3,"pid": 1,"text": "3,pid1"},
    {"id": 4,"pid": 3,"text": "4,pid3"},
    {"id": 5,"pid": 0,"text": "5,pid0"}
]}

实现的功能是生成树,第一层直接显示,点击节点可以隐藏显示子节点

[jquery]关于ajax+json,根据id pid生成树形结构

顺便把以前的传特殊结构的json生成树的代码贴了,文件结构:

images

    --m.png

    --p.png

pages

    --data.json

    --testJSON.html

testJSON.html的代码:

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>testJSON</title>
    <!-- <link rel="stylesheet" href="../css/jquery-ui.css"> -->
    <script src="../js/jquery-ui.js"></script>
    <style>
    li {
        margin-left: -5px;/*减少缩进长度,好看一点*/
        list-style-image: url("../images/p.png");
    }

    li:hover {
        cursor: pointer;
    }

    .hide {
        display: none;
    }

    #jsonArea {
        width: 350px;
    }
    </style>
</head>

<body>
    <div id="jsonArea">
    </div>
    <script src="http://code.jquery.com/jquery-1.8.3.js"></script>
    <script>
    var menulist = "";
    $.ajax({
        url: "data.json",
        data: {},
        type: "POST",
        dataType: "JSON",
        success: function(result) {
            menulist = result;
        }
    });
    // alert(menulist);
    console.log(menulist);
    $(function() {
        var showlist = $("<ul></ul>");
        showall(menulist.menulist, showlist);
        $("#jsonArea").append(showlist);
        $("#jsonArea ul li").find("li").addClass("hide");
        $("li").click(function() {
            if(!$(this).children("ul").length){// 没有子元素
                $(this).css("list-style-image", "url('../images/m.png')");
            }else if ($(this).children("ul").children("li").hasClass("hide")) {
            //若下li隐藏,则显示,并改图标
                $(this).children("ul").children("li").removeClass("hide");
                $(this).css("list-style-image", "url('../images/m.png')");
                // e.stopPropagation();
                return false;
            } else {
                //若下li显示,则隐藏下属所有li
                $(this).find("li").addClass("hide");
                //修改图标
                $(this).find("li").css("list-style-image", "url('../images/p.png')");
                $(this).css("list-style-image", "url('../images/p.png')");
                // e.stopPropagation();
                return false;
            }
            // e.stopPropagation();
            return false;
        });
    });

    //menu_list为json数据
    //parent为要组合成html的容器
    function showall(menu_list, parent) {   
        //for--start
        for (var menu in menu_list) {
            //如果有子节点,则遍历该子节点
            if (menu_list[menu].menulist.length > 0) {
                //创建一个子节点li
                //var li = $("<li style='list-style-image: url('../images/p.png')'></li>");
                var li = $("<li></li>");
                //添加li名称和下属ul子节点,并且加入父节点
                $(li).append(menu_list[menu].MName).append("<ul></ul>").appendTo(parent);
                //将空白的ul作为下一个递归遍历的父亲节点传入
                showall(menu_list[menu].menulist, $(li).children().eq(0));
            }
            //如果该节点没有子节点,则命名,加入父节点
            else {
                //$("<li style='list-style-image: url('../images/m.png')'></li>").append(menu_list[menu].MName).appendTo(parent);
                $("<li></li>").append(menu_list[menu].MName).appendTo(parent);
            }
        }
    }
    
    </script>
</body>

</html>

data.json:

{
    "menulist": [
    {
        "MName": "重点区域",
        "menulist": [
        {
            "MName": "南京城市管理",
            "menulist": [
            {
                "MName": "区县单位",
                "menulist": ""
            },
            {
                "MName": "执行总队",
                "menulist": [
                {
                    "MName": "玄武区大队",
                    "menulist": [
                    {
                        "MName": "中队1",
                        "menulist": ""
                    }]
                },
                {
                    "MName": "秦淮区大队",
                    "menulist": [
                    {
                        "MName": "中队1",
                        "menulist": ""
                    },
                    {
                        "MName": "中队2",
                        "menulist": ""
                    },
                    {
                        "MName": "中队3",
                        "menulist": ""
                    }]
                },
                {
                    "MName": "建邺区大队",
                    "menulist": [
                    {
                        "MName": "中队1",
                        "menulist": ""
                    },
                    {
                        "MName": "中队2",
                        "menulist": ""
                    }]
                }]
            }]
        }]
    },
    {
        "MName": "核心岗位",
        "menulist": [
        {
            "MName": "南京城市管理",
            "menulist": [
            {
                "MName": "区县单位",
                "menulist": ""
            },
            {
                "MName": "执行总队",
                "menulist": [
                {
                    "MName": "玄武区大队",
                    "menulist": [
                    {
                        "MName": "中队1",
                        "menulist": ""
                    },
                    {
                        "MName": "中队2",
                        "menulist": ""
                    }]
                },
                {
                    "MName": "秦淮区大队",
                    "menulist": [
                    {
                        "MName": "中队1",
                        "menulist": ""
                    }]
                }]
            }]
        }]
    }]
}

功能同样是点击可折叠/展开,并且有切换+ -符号表示状态的功能.


之后的想法是迭代一下,增加些实用功能,比如多选框, 不选(无) 部分选(方块) 全选(打勾),父子节点勾选的相互影响,保存节点勾选信息进数组并返回等.