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