<%@ page contentType="text/html; charset=gb2312"%> 实现基于 Ajax 的无限级菜单
网站公告:   ◆北天JAVA技术网热情为java爱好者服务,本网内容包括JAVA(JSP、servlet、EJB、webservice、j2ee、javabean、应用服务器、JavaScript),数据库(MYSQL、SQL Server、Sybase、Oracle、DB2、数据库综合知识),设计研究(设计模式、Struts、Spring、Hibernate、设计框架、设计综合知识),WEB2.0新技术(主要介绍AJAX),以及各种技术的入门、实例、例子等等,欢迎各位多来坐坐!◆  诚邀各位JAVA爱好者加盟!◆  本网站内容丰富,更新快,保证每周20篇以上!  
加入收藏
设为首页
联系站长
承接项目
  相关资源:网站首页 | 免费培训学院 | 技术论坛 | JAVA聊天室 | 作家专栏 | 开发工具 | 认证考试 | 会员俱乐部
  JAVA技术初学者园地 | jsp与servlet | javascript | Java源代码 | EJB | web service | 应用服务器 | JAVA综合知识
  设计研究设计模式 | 设计框架 | Struts | Spring | Hibernate | 开源项目 | 面向对象设计 | 设计综合知识
  数 据 库MYSQL | SQL Server | Sybase | Oracle | DB2 | Informix | Access | 数据库综合知识
  其他资源:AJAX新技术 | 网站开发 | ERP软件 | OA办公软件 | 商业智能BI | 开发综合知识 | 承接项目 | 项目试用

 
 
实现基于 Ajax 的无限级菜单
     发布者: 发布时间:2007-01-24
 

现在到处都有这方面的教程,我重点说一下我自己搞的一个框架。

特点:

支持Form的无闪提交(方法有点笨)

支持MVC框架,即支持传统网页架构

多线程并发请求(要语言支持线程)

动态加载文件,只加载有用的!处理了Ajax框架臃肿的JS文件问题。

采用no table的全div + css布局

a. 获得XMLHTTPRequest对象,网上到处都找得到了,不多说:

function newXMLHttpRequest() {

var xmlreq = false;

if (window.XMLHttpRequest) {

xmlreq = new XMLHttpRequest();

} else if (window.ActiveXObject) {

try {

xmlreq = new ActiveXObject("Msxml2.XMLHTTP");

} catch (e1) {

try {

xmlreq = new ActiveXObject("Microsoft.XMLHTTP");

} catch (e2) {

}

}

}

return xmlreq;

}

这里提供一个通用的支持多浏览器的方法。

b.提出异步请求

//这里用Bcandy作为方法名是为了感谢一个对我来说很重要的人,她一直在支持我

function Bcandy(Tid,url,parm,js) {

if(url == ""){

return;

}

//这是一个加载信息提示框,也可以不要!

document.getElementById("load").style.visibility = "visible";

//加载相应页面的JS文件

if(js != null){

//加载JS文件

LoadJS(js);

}

// 获取一个XMLHttpRequest实例

var req = newXMLHttpRequest();

// 设置用来从请求对象接收回调通知的句柄函数

var handlerFunction = getReadyStateHandler(req,Tid);

req.onreadystatechange = handlerFunction;

// 第三个参数表示请求是异步的

req.open("POST", url, true);

// 指示请求体包含form数据

req.setRequestHeader("Content-Type",

"application/x-www-form-urlencoded");

// 发送参数

req.send(parm);

}

function getReadyStateHandler(req,Tid) {

// 返回一个监听XMLHttpRequest实例的匿名函数

return function () {

// 如果请求的状态是“完成”

if (req.readyState == 4) {

// 成功接收了服务器响应

if (req.status == 200) {

//下面一句是重点,这里显示了返回信息的内容部分,也可以加以修改。进行其它处理

document.getElementById(Tid).innerHTML = req.responseText;

document.getElementById(Tid).style.visibility = "visible";

//这一句是实现加载信息提示框的隐藏,也可以不要。

document.getElementById("load").style.visibility = "hidden";

} else {

// 有HTTP问题发生

document.getElementById("load").style.visibility = "hidden";

alert("HTTP error: "+req.status);

}

}

}

}

//动态加载JS文件

function LoadJS(file){

var head = document.getElementsByTagName('HEAD').item(0);

var script = document.createElement('SCRIPT');

script.src = file;

script.type = "text/javascript";

head.appendChild(script);

}

这就是基本的框架了,因为使用了request.responseText;所以,可以直接请求一个页面jsp,servlet但在使用Struts框架的请求时要进行特殊处理,因为Form不支持异步请求。建议在这些页面上不要加入标签,就像.net里的asxm文件!而且在使用Struts框架时有点要注意的是,Mapping对象直接返回null就可以了,因为我们会在下面讲到并发多线程。来处理这个问题的。

总的来看,有点像是积木搭建起来的。这样方便文件的修改和扩展,互相之间并不影响,而且,实现了代码和标签分离。在进行传统页面改版时,也不用重新编写全部代码。只要修改一小部分就可以完美实现Ajax带来的无闪刷新快感。

以上代码均在IE,FireFox下测试过!

首先建立一个数据表menu

mId  菜单主键

name 菜单名称

url  菜单链接

father 低级菜单ID

sub  是否最底层菜单(用于判断是否还可以继续展开)

target 菜单链接目标(用ajax方式打开时作为显示id)

pa   菜单参数(这项用于ajax方式打开菜单)

制作一个菜单对象类

class Menu{

private int mId;

private String name;

...//其它成员

public getMid(){

return mId;

}

public setMid(int mId){

this.mId = mId;

}

....//其它成员的get set方法,

}

另一个是操作类

class MenuOpt(){

public Vector getMenus(int father){

Vector vector = new Vector();

//这里是取得父级菜单ID为father的全部菜单

//并封装进Vector的一个对象中。。

return vector;

}

}

其次就是一般的jsp文件了。但要注意以前说过的,不要包含标签!

menu.jsp:

%@page contentType="text/html; charset=GB2312"%>

%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

jsp:useBean id="menu" scope="page" class="ycoe.basic.MenuOpt"/>

jsp:setProperty name="menu" property="father" value="${param.father}"/>

div>

c:forEach var="m" items="${menu.vector}" varStatus = "c">

c:choose>

c:when test="${m.sub eq 'Y'}">

div onClick="showMenu('${m.mid}','${m.url}','${m.target}','father=${m.mid}')">

img src="pic/menu0.gif" id="img${m.mid}" alt="" style=" cursor:hand;">

a href="#" class="text1">${m.name}

/div>

div style="display:none;" id="tr${m.mid}">

div style="padding-left:12pt" id="${m.mid}">

/div>

/c:when>

c:otherwise>

div onclick="openMenu('${m.url}','${m.target}','${m.pa}');">

img src="pic/menu1.gif" id="img${m.mid}" alt="">

a href="#" class="text1">${m.name}

/div>

menu.js:

//operMenu(打开下拉菜单的ID,打开的地址,链接打开的目标,参数)。

//这是用在menu.jsp的方法

function showMenu(id,url,target,param){

var trObj = document.getElementById("tr"+id);

var tdObj = document.getElementById(id);

//try{

if(document.getElementById("tr"+id).style.display == "none"){

//显示菜单

if(tdObj.innerHTML == null || tdObj.innerHTML == ""){

//提取数据

document.getElementById("tr"+id).style.display = "";

document.getElementById("img"+id).src = "pic/menu2.gif"

Bcandy(id,"page/menu.jsp",param,"");

openMenu(url,target,param);

}else{

//如果里面有内容,直接显示

document.getElementById("tr"+id).style.display = "";

document.getElementById("img"+id).src = "pic/menu2.gif"

openMenu(url,target,param);

}

//Bcandy(target,url,param,"");//打开菜单链接

}else{

//隐藏菜单

document.getElementById("tr"+id).style.display = "none";

document.getElementById("img"+id).src = "pic/menu0.gif"

}

//}catch(e){}

}

//打开菜单

function openMenu(url,target,param){

//这里不用我写了吧。有好几种实现方法,建议使用ajax实现!

}

最后是显示页面:

%@ page contentType="text/html; charset=GB2312" %>

meta http-equiv=Content-Type content="text/html; charset=gb2312">

style>

.text1:hover { border: 1px #999999 solid; background-color: #CCCCCC; height: 12px;}

.text1{border: 1px #FFFFFF solid; height: 12px;}

function ini(){

Bcandy("0","menu.jsp","id=0&father=0","menu.js");

}

body onload="ini();">

div id="load" style="z-index:1; color:#FF0000; visibility:hidden; filter: Alpha(opacity=85); background-color:#FFFFFF; left: 48%; top: 48%;BORDER-RIGHT: #000000 1px solid; PADDING-RIGHT: 12px; BORDER-TOP: #000000 1px solid; PADDING-LEFT: 12px;PADDING-BOTTOM: 12px; BORDER-LEFT: #000000 1px solid; LINE-HEIGHT: 22px; PADDING-TOP: 12px; BORDER-BOTTOM: #000000 1px solid; POSITION: absolute;">

img src='pic/loop.gif' alt="">

数据处理中,请稍候...

br>

div id="0" align="center">

可以看到,无论在哪个层面,都和传统的没什么分别,只有jsp部分除去文件头而已(其实不去掉也行的,呵呵),而且,还可以看到,一个页面,已经分成了好几部分。就像之前说的那样,积木式的(这是网上看到一篇关于.net框架的结构时作者提出的一种结构,觉得不错,被我应用到JSP来了)。

在一些细节方面,我作了一些保留,请理解。但大致框架都是经过IE和FireFox测试。一些功能方面的扩展,自己想想了。

原理:其实就是应用了页面递归!就和一般的递归方法一下,不过用在页面上而已

div id="tr${m.id}">

循环,将从封装进vector的对象逐一显示出来

for{

 if(如果是最上层菜单sub=N){

 div id="t${m.id}" onClick="ShowMenu(${m.father....})">

  显示菜单内容

 

 

 div style="display:none" id="td${m.id....}">

 }else{

  div onClick="OpenMenu(${m.id})">显示菜单内容

 }

}

showMenu(father,id....)方法,将根据传入的father去服务器里取得数据后,再次调用这个页面。而这时,是将页面的内容显示在新的ID里面。这样,看起来就有和MSDN里的树菜单一样的效果了。

优点:多级菜单多次获取,加快了反应速度,同时应用了ajax请求,让人感觉不到页面的闪烁,亲和力强。再者,可以JS里加入了代码,让用户不用每次点击都去获取服务器数据,而是先判断有没有内容,没有再取。。。同时,实现了菜单与页面的同步,在每打开一级菜单,都可以在相应的地方打开页面。同样,这个operMenu()也可以采用ajax方式。

效果可以上 http://www.start.com/ 看看:

(转载文章请保留出处:北天JAVA技术网(www.java114.com))
 
更多精彩文章:
AJAX框架汇总
虚幻的web2。0和没有身世的博客
web2概念(1):从web整体结构看本质
我的WEB2 瞎想
新的网络招聘-基于垂直搜索和web2的新模式
一个最简单的Ibatis的使用
 
最近评论:
        
回复:实现基于ajax的无限级菜单
新译通翻译公司成立于1997年,经过多年的发展,已经成为中国最具权威的专业翻译公司之一,专业提供英语翻译、日语翻译、德语翻译、法语翻译、俄语翻译、韩语翻译、阿拉伯语翻译等的大型翻译公司! 新译通上海翻译公司是知名品牌上海翻译公司,凭借我们团队的不断努力,已成为世界大型公司选择上海翻译公司的首选.北京翻译公司.
        
回复:实现基于ajax的无限级菜单
上海高工阀门厂系我国通用机械行业协会成员单位,是集科研、设计、制造、服务于一体的高新技术企业,快速选择产品: 压差旁通阀; 遥控浮球阀; 止回阀; 排气阀; 闸阀; 气动蝶阀; 排气阀; 平衡阀; 阻火器; 减压阀过滤器调节阀
        
回复:实现基于ajax的无限级菜单
The site is selling cheap Maple Story Mesos (mesos,money) in maple story.we sell maple story money and maple story item in maple story only,not ms ... Delivery time less than 10 Mins. We will never use maplestory mesos hacks tool to make the maple story meso. eve online isk, eve isk, ao credits, anarchy online credits.
        
回复:实现基于ajax的无限级菜单
新译通翻译公司(北京翻译公司/上海翻译公司/广州翻译公司/深圳翻译公司),翻译公司是一家专业翻译公司,对翻译业务流程和质量控制标准化.提供及时、准确、规范的翻译服务,可提供多语种、多行业的翻译业务,是一家十分专业的翻译公司. 北京翻译公司,上海翻译公司.
        
回复:实现基于ajax的无限级菜单
提供昆明旅游服务,昆明旅游报价,昆明旅游线路,含昆明旅游、大理旅游、 丽江旅游、香格里拉旅游、泸沽湖旅游。云南旅游 提供昆明旅行社服务,昆明旅行社报价,昆明旅行社线路! 此外我们还提供昆明旅行社出港打折机票和昆明旅行社特价酒店预订服务。云南旅行社 提供丽江旅游服务,丽江旅游报价,丽江旅游线路,含丽江旅游、大理旅游!此外我们还提供丽江旅游出港打折机票和丽江旅游特价酒店预订服务。云南丽江丽江旅游
        
回复:实现基于 Ajax 的无限级菜单
去他妈的
        
标 题:   
内 容:   
 
                                  
 
免责声明:该文章由网友发表,如果对您造成侵权,请联系站长

首页 - 承接项目 - 网站地图 - 联系我们 -
版权所有北天JAVA技术工作室 ICP证号:粤ICP备06079815号