最近做“点滴”的时候,需要用到二级菜单,就是那种二级菜单的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"}
];
Java
--Java Book
--Java Code
C
1.首先,将一级菜单放入新的json数组中,并按id排序。
2.将剩余的二级菜单放入新的json数组中,并按pid排序。
3.遍历一级菜单的json数组,生成html,并检查二级菜单的json数组,是否有该一级菜单的子菜单,如果有,生成html,
4.完成。
上代码:
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:
javascript:
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 = $("
").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 = $("").addClass('sub_li_1').attr({"id":id,"pid":pid});
var sub_li_1_tile = $("").addClass('menu_title').text(name);
$(sub_li_1).append(sub_li_1_tile);
var sub_menu_1 = $('
').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 = $('').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.csdn.net/detail/mchange/5885037