注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

山林客

简单不一定幸福,但幸福其实可以很简单。

 
 
 

日志

 
 
关于我

2004年毕业于中山大学,毕业后专注于网站开发和网络工程技术。先后取得SCWCD、CCNP认证,对Asp/Java有丰富的开发经验,对网络工程也有较深的研究。真诚欢迎大家多多指教、多多指点、多多指正,共同分享IT道路和人生道路上的喜怒哀乐。

利用jQuery实现带缓存的无限级树形菜单  

2009-10-31 16:48:40|  分类: Web标准 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

AH-BILL近日在做一个JavaEE项目的时候,要实现一种无限级菜单,由于分类有n层,而且每个分类都有很多子分类,如果一次性加载,对客户端和服务器都会带来不利的影响。
为此我尝试借助jQuery来实现这种效果。我们要实现的效果是,当点击下图中的“加号”的时候则展开下一级分类,如果点击“减号”则收缩下一级分类。

我这里一共用到两个jsp页面,主页面显示主分类,而子分类则通过Ajax从另一个页面中读取。

首先是主页面:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Insert title here</title>
  <link type="text/css" href="../css/admin.css" rel="stylesheet" rev="stylesheet" />
<script src="../js/jquery.js" type="text/javascript"></script>
<script type="text/javascript">
<!--
$(document).ready(function() {
 $(".showhide").click(
  showfunc=function(){
  if($(this).attr("class").indexOf("minusIcon")==-1)
  {
  var now = new Date().getTime();
  var id = $(this).attr("id");
  id=id.substring(2);
  var subid="#s_"+id;
  var cache=$(subid).data("cache");
  if(cache==null){
  $.ajax({
     type: "GET",
     url: "subCategory.action?id="+id+"&t="+now,
     success: function(msg){
      
       $(subid).html(msg);
       $(subid).data("cache",msg);//缓存数据
       $(".showhide").click(showfunc);
      
     }
  });
  }else{
  $(subid).html(cache);
  $(".showhide").click(showfunc);
  }
  }
  $(this).toggleClass("minusIcon");
  $(this).nextAll(".subCategory").toggleClass("hide");
   
  }
 );
});
//-->
</script>
<style type="text/css">
.hide {
 display: none;
}

.show {
 display: block;
}

.plusIcon,.minusIcon,.minusIcon2 {
 float: left;
 width: 14px;
 height: 14px;
 cursor: pointer;
 background: url(../images/admin/plus.gif);
}

.minusIcon,.minusIcon2 {
 background: url(../images/admin/minus.gif);
}

.minusIcon2 {
 cursor: default;
}

//略...
</style>
</head>
<body>
//略,每一个一级分类的代码如下
<div class="block">
//如果有一级分类有子分类,则输出以下内容
 <div class="showhide plusIcon"
  id="c_1"></div>
 <div class="categoryName">家用电器</div>
 <div class="buttons btnModify">修改</div>
 <div class="buttons btnDelete">删除</div>
 <div class="buttons btnAdd">添加子分类</div>
 <div class="subCategory hide" id="s_1">
 </div>
//如果一级分类没有子分类,则输出以下内容
 <div class="minusIcon2"></div>
 <div class="categoryName">家用电器</div>
 <div class="buttons btnModify">修改</div>
 <div class="buttons btnDelete">删除</div>
 <div class="buttons btnAdd">添加子分类</div>
</div>
//略...
</body>
</html>

本文目的是阐述jQuery而不是JavaEE的相关技术,所以我这里省去了后台的所有代码。在<body>部分,我们看到一级分类显示的效果可能有两种,它们的主要差别主要有两个,即分类前面显示加号还是减号,以及是否输出
<div class="subCategory hide" id="s_1"></div>
在这个例子中,“家用电器”有子分类,所以输出会是上面那一种。
注意这里的加号和减号都是利用CSS的class来实现的,而不是一张图片,即下面这段代码。
.plusIcon,.minusIcon,.minusIcon2 {
 float: left;
 width: 14px;
 height: 14px;
 cursor: pointer;
 background: url(../images/admin/plus.gif);
}

.minusIcon,.minusIcon2 {
 background: url(../images/admin/minus.gif);
}

.minusIcon2 {
 cursor: default;
}

另外我们还需要编写一个页面,用来输出子分类的信息,它的内容其实跟上面body中的部分是完全一样的,例如:
<div class="block">
 <div class="minusIcon2"></div>
 <div class="categoryName">空调机</div>
 <div class="buttons btnModify">修改</div>
 <div class="buttons btnDelete">删除</div>
 <div class="buttons btnAdd">添加子分类</div>
</div>
<div class="block">
 <div class="showhide plusIcon" id="c_3"></div>
 <div class="categoryName">电脑</div>
 <div class="buttons btnModify">修改</div>
 <div class="buttons btnDelete">删除</div>
 <div class="buttons btnAdd">添加子分类</div>
 <div class="subCategory hide" id="s_3"></div>
</div>
可以看到“空调机”没有子分类,所以输出的是减号,而“电脑”下面还有子分类,所以显示为加号,而且输出了<div class="subCategory hide" id="s_3"></div>
这里我们还要留意,就是<div class="subCategory hide" id="s_3"></div>中的id和加号中的id后面的数字是相同的,这里都是“3”。

接下来我们回过头来看JavaScript代码,详见代码中的注释
<script type="text/javascript">
<!--
$(document).ready(function() {
 $(".showhide").click( //当点击“加号”或“减号”图标的时候执行————————(1)
  showfunc=function(){ //注意这里用一个变量名“showfunc”来保存这个函数,这是实现无限级树形菜单的关键
  if($(this).attr("class").indexOf("minusIcon")==-1) //当图标是“加号”
  {
  var now = new Date().getTime(); //取得当前时间
  var id = $(this).attr("id"); //得到图标的id
  id=id.substring(2); //得到图标id中的数字,目的是为了找到其对应的subCategory元素
  var subid="#s_"+id; //得到包裹子分类的div
  var cache=$(subid).data("cache"); //得到上述div的缓存数据
  if(cache==null){ //如果没有对应的缓存数据,则通过Ajax来从服务器查询数据
  $.ajax({
     type: "GET",  //使用GET方式读取子分类数据
     url: "subCategory.action?id="+id+"&t="+now,  //后台将根据id来得到子分类
     success: function(msg){
       $(subid).html(msg);  //msg是服务器返回的内容,将其加载到subCategory中
       $(subid).data("cache",msg);//将服务器返回的子分类数据缓存,名称是“cache”
       $(".showhide").click(showfunc);  //为服务器返回的数据中对应的展开图标同样附加上showfunc函数,这个很关键,因为我们前面(1)中只能找到当前页面中的所有.showhide元素,对于服务器动态返回的.showhide是不起作用的,因此我们必须在这里主动为服务器返回的那些.showhide元素附加上showfunc函数
     }
  });
  }else{ //如果subCategory元素中已经有缓存的数据,则不用再去访问服务器,而是直接读取缓存数据
     $(subid).html(cache);
     $(".showhide").click(showfunc);
  }
  }
  $(this).toggleClass("minusIcon");   //将加号变为减号、减号变为加号
  $(this).nextAll(".subCategory").toggleClass("hide");  //将子分类div隐藏或显示
   
  }
 );
});
//-->
</script>

实际上,对于每一个分类,只有在第一次点击“加号”的时候才会去访问服务器,当点击“减号”或者再次点击“加号”的时候,都不需要读取服务器,这无疑很大程度上改善了用户的体验及减轻服务器的压力。我们可以借助FireFox的FireBug插件很清晰地看到这个过程。

 

  评论这张
 
阅读(4222)| 评论(2)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018