有兴趣的话,我们就看看是如何实现这样的效果的。
首先考察菜单的数据结构。在例子中,我们只用到了二级菜单,也就是说只有一层折叠。为了方便菜单的扩展,我打算将菜单内容做成 xml 文件。
xml 文件(menus.xml)结构本身就很清晰,基本上能以原样呈现菜单层次,代码如下:
代码:
<?xml version="1.0" encoding="gb2312"?>
<channels>
<channel>
<title>系统设置</title>
<menu>
<title>系统参数</title>
<href>#</href>
</menu>
<menu>
<title>系统菜单</title>
<href>#</href>
</menu>
<menu>
<title>系统参数</title>
<href>#</href>
</menu>
<menu>
<title>系统参数</title>
<href>#</href>
</menu>
</channel>
<channel>
<title>会员管理</title>
<menu>
<title>会员列表</title>
<href>#</href>
</menu>
<menu>
<title>会员列表</title>
<href>#</href>
</menu>
<menu>
<title>添加会员</title>
<href>#</href>
</menu>
<menu>
<title>系统参数</title>
<href>#</href>
</menu>
</channel>
<channel>
<title>图片管理</title>
<menu>
<title>图片列表</title>
<href>#</href>
</menu>
<menu>
<title>系统参数</title>
<href>#</href>
</menu>
<menu>
<title>系统参数</title>
<href>#</href>
</menu>
<menu>
<title>系统参数</title>
<href>#</href>
</menu>
</channel>
<channel>
<title>系统设置</title>
<menu>
<title>系统参数</title>
<href>#</href>
</menu>
<menu>
<title>系统参数</title>
<href>#</href>
</menu>
<menu>
<title>系统参数</title>
<href>#</href>
</menu>
<menu>
<title>系统参数</title>
<href>#</href>
</menu>
</channel>
<channel>
<title>系统设置</title>
<menu>
<title>系统参数</title>
<href>#</href>
</menu>
<menu>
<title>系统参数</title>
<href>#</href>
</menu>
<menu>
<title>系统参数</title>
<href>#</href>
</menu>
<menu>
<title>系统参数</title>
<href>#</href>
</menu>
</channel>
</channels>
在 HTML 页面中我们需要加在该 xml 来生成菜单对应的 HTML 代码。加载 XML 文件的方式有很多种,但是鉴于我正好在学习 AJAX 应用,我就用了这个。
在 IE 中,XMLHttp 是通过 activeX 组件来实现的,这和 Mozilla 系列的不一样。通过下面部分代码,可以处理好浏览器的兼容性:
代码:
var xmlhttp = false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
// JScript gives us Conditional compilation, we can cope with old IE versions.
// and security blocked creation of the objects.
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (E) {
xmlhttp = false;
}
}
@end @*/
if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
xmlhttp = new XMLHttpRequest();
}
代码:
xmlhttp.open("GET", "menus.xml", true);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
var s = "";
var objXml = xmlhttp.responseXML;
var objDocument = objXml.documentElement;
var arrChannels = objDocument.childNodes;
var arrChannels = objXml.getElementsByTagName("channel");
var objChannel;
var objMenu;
for (var i = 0; i < arrChannels.length; i++) {
objChannel = arrChannels[i];
if (objChannel.childNodes[0].nodeType == 3) { // 判断第一个节点类型
s = s + "<div class=\"menuTitle\" onClick=\"showHideMenu(this);\"><span> </span>" + objChannel.childNodes[1].childNodes[0].nodeValue + "</div>";
s = s + "<div class=\"menuContent\"><ul>";
for (var k = 1; k < Math.floor((objChannel.childNodes.length / 2)); k++) {
objMenu = objChannel.childNodes[2 * k + 1];
s = s + "<li><a href=\"" + objMenu.childNodes[3].childNodes[0].nodeValue + "\" title=\"" + objMenu.childNodes[1].childNodes[0].nodeValue + "\" target=\"mainFrame\">" + objMenu.childNodes[1].childNodes[0].nodeValue + "</a></li>";
}
s = s + "</ul></div>";
}
else { // IE
s = s + "<div class=\"menuTitle\" onClick=\"showHideMenu(this);\"><span> </span>" + objChannel.childNodes[0].childNodes[0].nodeValue + "</div>";
s = s + "<div class=\"menuContent\"><ul>";
for (var k = 1; k < objChannel.childNodes.length; k++) {
objMenu = objChannel.childNodes[k];
s = s + "<li><a href=\"" + objMenu.childNodes[1].childNodes[0].nodeValue + "\" title=\"" + objMenu.childNodes[0].childNodes[0].nodeValue + "\" target=\"mainFrame\">" + objMenu.childNodes[0].childNodes[0].nodeValue + "</a></li>";
}
s = s + "</ul></div>";
}
}
document.getElementById("menus").innerHTML = s;
}
}
xmlhttp.send(null);
好了,结构生成了,现在就是如何操作菜单的显示与隐藏。
代码:
function showHideMenu(o) {
var objTitle = o;
// 有一个文本节点,可能是换行符
// IE 下面的效果有些问题
// responseXML 获得的代码中不包含这个换行
//var objContent
//if (document.all) {
objContent = objTitle.nextSibling;
//}
//else {
//objContent = objTitle.nextSibling.nextSibling;
//}
var objSpan = objTitle.childNodes[0];
if (objContent.style.display != "block") {
objContent.style.display = "block";
objSpan.className = "arrowOpen"
}
else {
objContent.style.display = "none";
objSpan.className = "arrowClose"
}
}
其它的就是关于菜单的样式了,使之如何美观。








利用了一点 AJax 知识的折叠菜单











平板模式