返回   CHF站长论坛 > 综合讨论区 > 网站开发与设计

网站开发与设计 网页设计、网站开发、网站维护与调试交流区。

双至强仅二千,企商在线,最早租用商 传世私服 魔域私服 亿恩1元帮您升级服务器! 天龙八部私服 传奇世界私服
站长轻松日赚500,日结稳定高价,QQ:705491 705492 英雄合击 热血江湖私服 传奇私服 传奇私服 传世私服 完美世界私服 魔域私服 传奇私服
发表新主题 回复
 
主题工具 主题评分 显示模式
旧 2005-09-27, 14:22   #1 (页面定位)
不学无术
Ulysses 的元神
 
不学无术 的头像
 
注册日期: 2005-08-31
住址: 冥王星
帖子: 13743
不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀
默认 利用了一点 AJax 知识的折叠菜单

先看看演示:在线演示

有兴趣的话,我们就看看是如何实现这样的效果的。

首先考察菜单的数据结构。在例子中,我们只用到了二级菜单,也就是说只有一层折叠。为了方便菜单的扩展,我打算将菜单内容做成 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>
其中每个 channel 节点对应一个折叠菜单,每个 menu 对应一个子菜单项。title 节点是要显示的 链接文本,href 是链接路径。当然根据需要还可以加上能表示 a 元素的其它属性的节点。

在 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();
    }
后面就是利用 XMLHttpRequest 来加载 XML 文档,并对返回的 XML 内容进行分析,以生成对应的 HTML 代码:

代码:
	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>&nbsp;</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>&nbsp;</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);
在这个应用中我们还是需要注意浏览器的区别。因为对于上面格式化的 XML 文档,不同的节点间有一个空格,IE 中会忽略,但是其它大多数浏览器会将其作为一个文本类型的节点来处理。

好了,结构生成了,现在就是如何操作菜单的显示与隐藏。

代码:
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"
	}
}
这里利用了一点 DOM 知识。当我们点击菜单标题的时候,我们就驱动上面的程序。o 代表执行了点击操作的菜单标题 <div> ,然后可以通过 nextSibling 来获得下一个节点,即掩藏或者显示的菜单区域 <div> ,这样我们就可以通过样式表中的 display 来控制菜单的显隐了。“block”表示显示,“none”表示隐藏。

其它的就是关于菜单的样式了,使之如何美观。
不学无术 当前离线   回复时引用此帖
旧 2005-09-27, 14:22   #2 (页面定位)
不学无术
Ulysses 的元神
 
不学无术 的头像
 
注册日期: 2005-08-31
住址: 冥王星
帖子: 13743
不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀
默认

HTML 文件(left.html)的全部代码(包括 CSS / JavaScript)如下:

代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>折叠菜单</title>
<style type="text/css">
<!--
body {
	background: #FFFFFF;
	margin: 0px;
	padding: 0px;
}
body, table, td, th, tr, input, button, select, textarea, div, span {
	font: 12px "宋体", sans-serif;
}

/* ---- 左栏 ---- */
.leftFrame {
    background: #C3CDDE;
}
#menus {
    width: 160px;
}
.menuTitle {
    font-size: 12px;
    /*line-height: 20px;*/
	background: url(images/title_background.gif) no-repeat left center;
	text-align: left;
	/*height: 20px;*/
	padding: 4px 0 2px 14px;
	cursor: default;
}
.menuTitle span {
    background: url(images/title_arrow_close.gif) no-repeat center center;
	width: 9px;
	height: 12px;
	margin-right: 3px;
	float: left;
	cursor: default;
}
.menuTitle span.arrowOpen {
    background: url(images/title_arrow_open.gif) no-repeat center center;
}
.menuTitle span.arrowClose {
    background: url(images/title_arrow_close.gif) no-repeat center center;
}
.menuContent {
    font-size: 12px;
	line-height: 150%;
	background: #FFFFFF;
	display: none;
	padding: 10px;
	overflow: auto;
}
.menuContent ul {
    padding: 0;
	margin: 0;
	list-style: none;
}
.menuContent ul li {
    background: url(images/dot.gif) no-repeat left center;
	padding-left: 12px;
}
.menuContent a {
    color: #000000;
	text-decoration: none;
}
.menuContent a:hover {
    color: #3030C0;
	text-decoration: none;
}
p.copy {
    font-size: 12px;
	line-height: 150%;
	background: #DEE3ED;
	padding: 10px;
	border-top: 1px solid #626B7B;
	border-bottom: 1px solid #626B7B;
}

/* ---- 左栏 ---- */
-->
</style>
<script language="javascript" type="text/javascript">
<!--
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"
	}
}

function setMenus() {
    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>&nbsp;</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>&nbsp;</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);
}
-->
</script>
</head>

<body class="leftFrame" onLoad="setMenus();">
<div id="menus"></div>
<p class="copy">
  版面设计:不学无术
  <br>

  程序制作:不学无术
  <br>
  版权所有:<a href="http://www.onlyidc.com/" title="访问 趋势科技" target="_blank">趋势科技</a>
</p>
</body>
</html>


不善于写教程,只是简单介绍了一下思路,欢迎大家交流。
不学无术 当前离线   回复时引用此帖
旧 2005-09-27, 18:49   #3 (页面定位)
老林©
 
老林 的头像
 
注册日期: 2005-09-06
帖子: 10358
老林 即将成为的新星老林 即将成为的新星老林 即将成为的新星老林 即将成为的新星老林 即将成为的新星老林 即将成为的新星老林 即将成为的新星老林 即将成为的新星老林 即将成为的新星老林 即将成为的新星老林 即将成为的新星
默认

支持一下
老林 当前离线   回复时引用此帖
旧 2005-09-27, 19:54   #4 (页面定位)
小叶
 
注册日期: 2005-09-04
住址: 火星人
帖子: 17759
小叶 是一位成功的新星小叶 是一位成功的新星小叶 是一位成功的新星小叶 是一位成功的新星小叶 是一位成功的新星小叶 是一位成功的新星小叶 是一位成功的新星小叶 是一位成功的新星小叶 是一位成功的新星小叶 是一位成功的新星小叶 是一位成功的新星
默认

太服你了..每天你在我背后坐着不知捣鼓什么,,,
出来这么牛的玩意.


匆匆人生中,你做了几件令自己骄傲的事呢?
小叶 当前离线   回复时引用此帖
旧 2005-09-30, 11:23   #5 (页面定位)
wm_chief©
 
wm_chief 的头像
 
注册日期: 2005-09-05
帖子: 17782
wm_chief 有着人尽皆知的贡献和荣耀wm_chief 有着人尽皆知的贡献和荣耀wm_chief 有着人尽皆知的贡献和荣耀wm_chief 有着人尽皆知的贡献和荣耀wm_chief 有着人尽皆知的贡献和荣耀wm_chief 有着人尽皆知的贡献和荣耀wm_chief 有着人尽皆知的贡献和荣耀wm_chief 有着人尽皆知的贡献和荣耀wm_chief 有着人尽皆知的贡献和荣耀wm_chief 有着人尽皆知的贡献和荣耀wm_chief 有着人尽皆知的贡献和荣耀
默认

不错的东东
wm_chief 当前离线   回复时引用此帖
旧 2005-09-30, 11:26   #6 (页面定位)
yeshou
 
yeshou 的头像
 
注册日期: 2005-09-06
帖子: 7029
yeshou 有着人尽皆知的贡献和荣耀yeshou 有着人尽皆知的贡献和荣耀yeshou 有着人尽皆知的贡献和荣耀yeshou 有着人尽皆知的贡献和荣耀yeshou 有着人尽皆知的贡献和荣耀yeshou 有着人尽皆知的贡献和荣耀yeshou 有着人尽皆知的贡献和荣耀yeshou 有着人尽皆知的贡献和荣耀yeshou 有着人尽皆知的贡献和荣耀yeshou 有着人尽皆知的贡献和荣耀yeshou 有着人尽皆知的贡献和荣耀
默认

太长了。。。


这家伙太懒,什么也没留下
yeshou 当前离线   回复时引用此帖
旧 2005-09-30, 14:11   #7 (页面定位)
不学无术
Ulysses 的元神
 
不学无术 的头像
 
注册日期: 2005-08-31
住址: 冥王星
帖子: 13743
不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀不学无术 有着人尽皆知的贡献和荣耀
默认

引用:
作者: yeshou
太长了。。。
现学现卖,让您见笑了!

以后还请多多指教呢
不学无术 当前离线   回复时引用此帖
旧 2005-09-30, 17:12   #8 (页面定位)
chandler
 
chandler 的头像
 
注册日期: 2005-09-27
住址: 北京
帖子: 1942
chandler 是一个将要出名的人chandler 是一个将要出名的人chandler 是一个将要出名的人chandler 是一个将要出名的人chandler 是一个将要出名的人chandler 是一个将要出名的人
默认

引用:
作者: web
太服你了..每天你在我背后坐着不知捣鼓什么,,,
出来这么牛的玩意.
JJ?


引用:
从现在开始,我只疼你一个,宠你,不会骗你。答应你的每一件事情,我都会做到;
对你讲的每一句话,都是真话。
不气你,不骂你,相信你。有人欺负你,我会第一时间出来帮你。
你开心的时候,我会陪着你开心; 你不开心,我也会哄得你开心。
永远,都觉得你最漂亮;做梦,都会梦见你;在我的心里,只有你。
不管你记不记得我,你永远,都是我老婆…
chandler 当前离线   回复时引用此帖
回复

书签

标签

主题工具
显示模式 对此主题评分
对此主题评分:



所有时间均为北京时间。现在的时间是 03:23