ajax级联:Ajax 的无限级菜单来源: 发布时间:星期四, 2009年2月12日 浏览:112次 评论:0
特点: 支持Form无闪提交(思路方法有点笨) 支持MVC框架即支持传统网页架构 多线程并发请求(要语言支持线程) 动态加载文件只加载有用!处理了Ajax框架臃肿JS文件问题 采用notable全div+css布局 a.获得XMLHTTPRequest对象网上到处都找得到了不多说: functionXMLHttpRequest{ varxmlreq=false; (window.XMLHttpRequest){ xmlreq=XMLHttpRequest; }(window.ActiveXObject){ try{ xmlreq=ActiveXObject(\"Msxml2.XMLHTTP\"); }catch(e1){ try{ xmlreq=ActiveXObject(\"Microsoft.XMLHTTP\"); }catch(e2){ } } } xmlreq; } 这里提供个通用支持多浏览器思路方法 b.提出异步请求 //这里用Bcandy作为思路方法名是为了感谢个对我来说很重要人她直在支持我 functionBcandy(Tid,url,parm,js){ (url\"\"){ ; } //这是个加载信息提示框也可以不要! document.getElementById(\"load\").style.visibility=\"visible\"; //加载相应页面JS文件 (js!=null){ //加载JS文件 LoadJS(js); } //获取个XMLHttpRequest例子 varreq=XMLHttpRequest; //设置用来从请求对象接收回调通知句柄 varhandlerFunction=getReadyStateHandler(req,Tid); req.onreadystatechange=handlerFunction; //第 3个参数表示请求是异步 req.open(\"POST\",url,true); //指示请求体包含form数据 req.RequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\"); //发送参数 req.send(parm); } functiongetReadyStateHandler(req,Tid){ //返回个监听XMLHttpRequest例子匿名 function{ //如果请求状态是“完成” (req.readyState4){ //成功接收了服务器响应 (req.status200){ //下面句是重点这里显示了返回信息内容部分也可以加以修改进行其它处理 document.getElementById(Tid).innerHTML=req.responseText; document.getElementById(Tid).style.visibility=\"visible\"; //这句是实现加载信息提示框隐藏也可以不要 document.getElementById(\"load\").style.visibility=\"hidden\"; }{ //有HTTP问题发生 document.getElementById(\"load\").style.visibility=\"hidden\"; alert(\"HTTPerror:\"+req.status); } } } } //动态加载JS文件 functionLoadJS(file){ varhead=document.getElementsByTagName(’HEAD’).item(0); varscript=document.createElement(’SCRIPT’); script.src=file; [Page] script.type=\"text/javascript\"; head.appendChild(script); } 这就是基本框架了使用了request.responseText;所以可以直接请求个页面jsp,servlet但在使用Struts框架请求时要进行特殊处理Form不支持异步请求建议在这些页面上不要加入标签就像.net里asxm文件!而且在使用Struts框架时有点要注意是Mapping对象直接返回null就可以了我们会在下面讲到并发多线程来处理这个问题 总来看有点像是积木搭建起来这样方便文件修改和扩展互相的间并不影响而且实现了代码和标签分离在进行传统页面改版时也不用重新编写全部代码只要修改小部分就可以完美实现Ajax带来无闪刷新快感 以上代码均在IEFireFox下测试过! 首先建立个数据表menu mId 菜单主键 name 菜单名称 url 菜单链接 father 低级菜单ID sub 是否最底层菜单(用于判断是否还可以继续展开) target 菜单链接目标(用ajax方式打开时作为显示id) pa 菜单参数(这项用于ajax方式打开菜单) 制作个菜单对象类 Menu{ privatemId; privateStringname; ...//其它成员 publicgetMid{ mId; } publicMid(mId){ this.mId=mId; } ....//其它成员get思路方法 } 另个是操作类 MenuOpt{ publicVectorgetMenus(father){ Vectorvector=Vector; //这里是取得父级菜单ID为father全部菜单 //并封装进Vector个对象中 vector; } } 其次就是般jsp文件了但要注意以前说过不要包含标签! menu.jsp: %@pagecontentType=\"text/html;char=GB2312\"%> %@tagliburi=\"http://java.sun.com/jsp/jstl/core\"prefix=\"c\"%> jsp:useBeanid=\"menu\"scope=\"page\"=\"ycoe.basic.MenuOpt\"/> jsp:Propertyname=\"menu\"property=\"father\"value=\"${param.father}\"/> div> c:forEachvar=\"m\"items=\"${menu.vector}\"varStatus=\"c\"> c:choose> c:whentest=\"${m.subeq’Y’}\"> divonClick=\"showMenu(’${m.mid}’,’${m.url}’,’${m.target}’,’father=${m.mid}’)\"> imgsrc=\"pic/menu0.g\"id=\"img${m.mid}\"alt=\"\"style=\"cursor:hand;\"> ahref=\"#\"=\"text1\">${m.name} /div> divstyle=\"display:none;\"id=\"tr${m.mid}\"> divstyle=\"padding-left:12pt\"id=\"${m.mid}\"> /div> /c:when> c:otherwise> divonclick=\"openMenu(’${m.url}’,’${m.target}’,’${m.pa}’);\"> imgsrc=\"pic/menu1.g\"id=\"img${m.mid}\"alt=\"\"> ahref=\"#\"=\"text1\">${m.name} /div> menu.js: //operMenu(打开下拉菜单ID打开地址,链接打开目标参数) //这是用在menu.jsp思路方法 functionshowMenu(id,url,target,param){ [Page] vartrObj=document.getElementById(\"tr\"+id); vartdObj=document.getElementById(id); //try{ (document.getElementById(\"tr\"+id).style.display\"none\"){ //显示菜单 (tdObj.innerHTMLnull||tdObj.innerHTML\"\"){ //提取数据 document.getElementById(\"tr\"+id).style.display=\"\"; document.getElementById(\"img\"+id).src=\"pic/menu2.g\" Bcandy(id,\"page/menu.jsp\",param,\"\"); openMenu(url,target,param); }{ //如果里面有内容直接显示 document.getElementById(\"tr\"+id).style.display=\"\"; document.getElementById(\"img\"+id).src=\"pic/menu2.g\" openMenu(url,target,param); } //Bcandy(target,url,param,\"\");//打开菜单链接 }{ //隐藏菜单 document.getElementById(\"tr\"+id).style.display=\"none\"; document.getElementById(\"img\"+id).src=\"pic/menu0.g\" } //}catch(e){} } //打开菜单 functionopenMenu(url,target,param){ //这里不用我写了吧有好几种实现思路方法建议使用ajax实现! } 最后是显示页面: %@pagecontentType=\"text/html;char=GB2312\"%> metahttp-equiv=Content-Typecontent=\"text/html;char=gb2312\"> style> .text1:hover{border:1px#999999solid;background-color:#CCCCCC;height:12px;} .text1{border:1px#FFFFFFsolid;height:12px;} functionini{ Bcandy(\"0\",\"menu.jsp\",\"id=0&father=0\",\"menu.js\"); } bodyonload=\"ini;\"> divid=\"load\"style=\"z-index:1;color:#FF0000;visibility:hidden;filter:Alpha(opacity=85);background-color:#FFFFFF;left:48%;top:48%;BORDER-RIGHT:#0000001pxsolid;PADDING-RIGHT:12px;BORDER-TOP:#0000001pxsolid;PADDING-LEFT:12px;PADDING-BOTTOM:12px;BORDER-LEFT:#0000001pxsolid;LINE-HEIGHT:22px;PADDING-TOP:12px;BORDER-BOTTOM:#0000001pxsolid;POSITION:absolute;\"> imgsrc=’pic/loop.g’alt=\"\"> 数据处理中请稍候... br> divid=\"0\"align=\"center\"> 可以看到无论在哪个层面都和传统没什么分别只有jsp部分除去文件头而已(其实不去掉也行呵呵)而且还可以看到个页面已经分成了好几部分就像的前说那样积木式(这是网上看到篇有关.net框架结构时作者提出种结构觉得不错被我应用到JSP来了) 在些细节方面我作了些保留请理解但大致框架都是经过IE和FireFox测试些功能方面扩展自己想想了 原理:其实就是应用了页面递归!就和般递归思路方法下不过用在页面上而已 divid=\"tr${m.id}\"> 循环将从封装进vector对象逐显示出来 [Page] for{ (如果是最上层菜单sub=N){ divid=\"t${m.id}\"onClick=\"ShowMenu(${m.father....})\"> 显示菜单内容 divstyle=\"display:none\"id=\"td${m.id....}\"> }{ divonClick=\"OpenMenu(${m.id})\">显示菜单内容 } } showMenu(father,id....)思路方法将根据传入father去服务器里取得数据后再次这个页面而这时是将页面内容显示在新ID里面这样看起来就有和MSDN里树菜单样效果了 优点:多级菜单多次获取加快了反应速度同时应用了ajax请求让人感觉不到页面闪烁亲和力强 0
相关文章读者评论发表评论 |