利用json数据做父子二级菜单

本文介绍了如何利用JSON数据创建父子二级菜单,避免了数据库层的递归操作。通过将一级菜单和二级菜单分别排序,然后遍历一级菜单并结合二级菜单生成HTML,实现了这一功能。文中提供了HTML、JavaScript和CSS的实现代码,并展示了最终效果。

最近做“点滴”的时候,需要用到二级菜单,就是那种二级菜单的pid指向一级菜单的id的那种。


所以自己动手写了一个。


优势是:(可能是我见得少了,自以为优势的地方):

1.不用在数据库层做递归。只需要把数据查出来即可。(就是为了这点才写的,我用python,返回json比较容易,也比较舒服)

2.参见第一条。


思路:

[
{"name":"Java Book", "id":"3", "pid":"1"},
{"name":"C", "id":"2", "pid":"0"},
{"name":"Java", "id":"1", "pid":"0"},
{"name":"Java Code", "id":"4", "pid":"1"}
];

json数据如上,可以很混乱,符合特殊场景的需要。目标结构如下

Java

    --Java Book

    --Java Code

C


1.首先,将一级菜单放入新的json数组中,并按id排序。

2.将剩余的二级菜单放入新的json数组中,并按pid排序。

3.遍历一级菜单的json数组,生成html,并检查二级菜单的json数组,是否有该一级菜单的子菜单,如果有,生成html,

4.完成。


上代码:

html部分:

<html>
<head>
	<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
	<title>树形菜单</title>
	<link rel="stylesheet" href="jquery.jmenutree.css">
	<script src="jquery.js" type="text/javascript"></script>
	<script src="jquery.jmenutree.js" type="text/javascript"></script>
	<style>
		
	</style>
	
</head>
<body>
	
	<div id="menuWrapper">
		
	</div>

</body>

<script>
		
		//节点json数据
		var j_mJson = [{"name":"Java Book", "id":"4", "pid":"2"},
					   {"name":"C", "id":"2", "pid":"0"},
					   {"name":"Java", "id":"1", "pid":"0"},
					   {"name":"Java Code", "id":"3", "pid":"2"},
					   {"name":"cJava", "id":"21", "pid":"1"},
					   {"name":"cJava Code", "id":"13", "pid":"1"}
					  ];

		$(function(){
			$("#menuWrapper").jMenuTree({
				jValue:j_mJson,
				autoShow:false,
				click:function(node){         //node:点击的菜单对象
					alert($(node).attr("pid"));
				}

			});
			
		})
	</script>

</html>


js部分:


/*
	jMenuTree - 利用json数据显示二级菜单
	by 候鸟随风
	2013-08-06

	jValue样例:【pid指向父类id】
	[{"name":"Java Book", "id":"3", "pid":"1"},
	 {"name":"C", "id":"2", "pid":"0"},
	 {"name":"Java", "id":"1", "pid":"0"},
	 {"name":"Java Code", "id":"4", "pid":"1"}
	]

	调用样例:
	html:
		<div id="menuWrapper"></div>

	javascript:
		<script>
			
			//节点json数据
			var j_mJson = [{"name":"Java Book", "id":"3", "pid":"1"},
						   {"name":"C", "id":"2", "pid":"0"},
						   {"name":"Java", "id":"1", "pid":"0"},
						   {"name":"Java Code", "id":"4", "pid":"1"}
						  ];

			$(function(){
				$("#menuWrapper").jMenuTree({
					jValue:j_mJson,
					autoShow:false,
				});
				
			})
		</script>
	
	Dual licensed under MIT and GPL.
*/
;(function($){ 

	$.fn.extend({
		"jMenuTree":function(options){
			//设置默认值
			options = $.extend({
				jValue:"",  	//菜单所用json数据
				autoShow:false, //是否全部打开
				show:"",  		//子菜单显示的方法
				click:"",       //点击事件
			},options);


			//保存主菜单节点
			var _j_main_menu = [];
			//保存子菜单节点
			var _j_sub_menu = [];
			var _this = this;

			//json排序规则,按照id降序,一级菜单
			function sortId(a,b){
				return a.id-b.id;
			}

			//json排序规则,按照pid降序,二级菜单
			function sortPid(a,b){
				return a.pid-b.pid;
			}

			//将节点json数据排序分类
			function sortJson(json){
				var index_m = 0;
				var index_s = 0;
				json = json.sort(sortId);
				
				for(var i=0; i< json.length; i++){
					if(json[i].pid == 0){
						//归类主菜单节点
						_j_main_menu[index_m++] = json[i];
					}else{
						//归类子菜单节点
						_j_sub_menu[index_s++] = json[i];
					}
				}

				//排序:按id降序排列
				// _j_main_menu.sort(sortId);
				_j_sub_menu.sort(sortPid);
			}

			//构建html
			function buildMenu(json){
				//归类排序数据
				sortJson(json);

				//主菜单
				var menu_ul = $("<ul></ul>").addClass('jMenuTree');

				//遍历主菜单节点,生成html
				for(var i=0; i< _j_main_menu.length; i++){
					var name = _j_main_menu[i].name;
					var id = _j_main_menu[i].id;
					var pid = _j_main_menu[i].pid;

					var sub_li_1 = $("<li></li>").addClass('sub_li_1').attr({"id":id,"pid":pid});
					var sub_li_1_tile = $("<div></div>").addClass('menu_title').text(name);
					$(sub_li_1).append(sub_li_1_tile);

					

					var sub_menu_1 = $('<ul></ul>').addClass('sub_menu_1');

					if(options.autoShow){
						$(sub_menu_1).css("display","block");
					}

					//声明一个临时数组,保存剩余的子菜单节点,减少下次的遍历数量,提供效率
					var _jtemp = [];
					var _index_temp = 0;

					//如果主菜单包含二级菜单,构建子菜单html
					for(var j=0; j < _j_sub_menu.length; j++){
						var sname = _j_sub_menu[j].name;
						var sid = _j_sub_menu[j].id;
						var spid = _j_sub_menu[j].pid;

						if(id == spid){
							var sub_li_2 = $('<li></li>').addClass('sub_li_2')
								.attr({"id":sid, "pid":spid})
								.text(sname);

							$(sub_menu_1).append(sub_li_2);

						}else{
							_jtemp[_index_temp++] = _j_sub_menu[j];
						}
					}

					_j_sub_menu = _jtemp;
					_jtemp = null;
					_index_temp = 0;


					if($(sub_menu_1).find("li").length > 0){
						$(sub_li_1).append(sub_menu_1);
					}

					$(menu_ul).append(sub_li_1);
				}

				$(_this).append(menu_ul);
			}


			//注册显示子菜单事件
			var show = function(){
				$(".sub_li_1").find(".menu_title").click(function(){
					$(this).siblings().toggle('slow');
				});

			}
			
			//点击菜单事件
			var click = function(){
				$(".jMenuTree > li").click(function(){
					alert($(this).attr("id"));
				});
			}

			//阻止冒泡事件   
			var stopBubble = function(e) {   
			     if (e && e.stopPropagation) {//非IE   
			         e.stopPropagation();   
			     }   
			     else {//IE   
			         window.event.cancelBubble = true;   
			     }   
			 } 

			var init = function(){
				buildMenu(options.jValue);

				$(".sub_li_1").find(".menu_title").click(function(e){
		
					var $node = this;
					//检查用户是否自定义了显示方法
					if(typeof options.show  == "function"){
						options.show($node);
					}else{
						$($node).siblings().toggle('slow');
					}

					
				});
				
				$(".jMenuTree").find("li").click(function(e){
					stopBubble(e);

					var $node = this;

					if(typeof options.click  == "function"){
						options.click($node);
					}else{
						alert("你点击的id是:"+$($node).attr("id"));
					}
					
				});	
			}

			init();

			return this;
		}

	});



})(jQuery);


css样式:

.jMenuTree{
	list-style:none;
	color:#555555;
	font-size:12px;
	line-height: 20px;
}
		
.jMenuTree li{
	width:200px;
	padding-left: 10px;
	cursor: pointer;
}

.jMenuTree .sub_li_1{
	background-color: #F2F3F5;
	border:1px solid #555555;
	margin-top:5px;

}

.sub_menu_1{
	display: none;
}



效果图:



全部资源(免费):

http://download.youkuaiyun.com/detail/mchange/5885037

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值