利用jQuery兑现带缓存的无限级树形菜单
<!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插件很清晰地看到这个过程。