之前也练习过生成树的小功能,不过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"} ]}
实现的功能是生成树,第一层直接显示,点击节点可以隐藏显示子节点
顺便把以前的传特殊结构的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": "" }] }] }] }] }] }
功能同样是点击可折叠/展开,并且有切换+ -符号表示状态的功能.
之后的想法是迭代一下,增加些实用功能,比如多选框, 不选(无) 部分选(方块) 全选(打勾),父子节点勾选的相互影响,保存节点勾选信息进数组并返回等.