java结合jQuery.ajax实现左右菜单联动刷新列表内容
http://域名/一级菜单ID-二级菜单ID/
用这种URL请求页面,出现如图所看到的内容;
该页面包括四部分,顶部文件夹+左側菜单+右側菜单+右下側数据列表。
左側菜单包括一级菜单和二级菜单,点击某个一级菜单时打开相应的二级菜单。同一时候右側也显示二级菜单。选中左側某个二级菜单,右側相应的二级菜单也被选中,点击右側二级菜单,显示相应的三级菜单,默认选中三级菜单的所有,点击某个三级菜单。列表中展示相应菜单下的数据;上述所有点击过程中,顶部文件夹以及右側列表同一时候刷新。。。感觉好绕口的样子呢,只是我还是实现了它。。。
就当是做点笔记吧。
页面布局:父页面+iframe_menu+iframe_dataList
parent.jsp
<!-- 头部省略 --> <script type="text/javascript"> function queryDataByID(type_id) { handleDiv(type_id); } </script> </head> <% // 处理URL中的參数(一级菜单ID-二级菜单ID) String id= (String)request.getAttribute("id"); String realid = ""; String[] ids ; if(id.contains("-")){ ids = id.split("-"); if(ids.length==2){ realid = ids[1]; }else if(ids.length==3){ realid = ids[2]; } }else{ realid = id; } %> <body class="tf"> <p class="wrapper key"> <a href="#">门户站点</a><span>></span> <a href="#">链接1</a><span>></span> <a href="#">链接2</a><span>></span> <a href="" id="mulufirst"></a><span>></span> <em id="mulusecond"></em><!--标示当前--> </p> <div class="wrapper clearfix"> <!--***************************************************************左側菜单****************************************************************--> <div class="main_left"> <iframe onload="iframeMenuFun()" name="iframeMenu" src="/menu/fenlei/<%=id%>.html" height="950" width="250" frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling="no" style="float:left;"></iframe> </div> <!--***************************************************************左側菜单****************************************************************--> <div class="main_content"> <div class="mc_one" id="parentchild"></div> <!-- 加入横向一级和二级菜单 --> <div class="mc_one"> <ul class="mc_content"> <!--***************************************************************右側数据列表****************************************************************--> <iframe src="/listpart/<%=realid %>/1.html" align="top" id="iframepage" width="931" onload="SetWinHeight(this)" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" ></iframe> <!--***************************************************************右側数据列表****************************************************************--> </ul> </div> </div> </div> <script> function loadDatabyID(type_id){//依据三级id载入数据 document.getElementById("iframepage").src="/xf/listpart/"+type_id+"/1.html"; } function switchSanjiClass(o){ var oI=$(o).parent().find('a').index($(o)); $(o).parent().find('a').eq(oI).addClass('on').siblings().removeClass('on'); } function handleDiv(type_id){ var temp = type_id.replace("r","s"); $('.main_content #parentchild >div').each(function () {//遍历处理隐藏的三级菜单 if($(this).attr("id")==temp){ if ($(this).hasClass('Hide')) { $(this).removeClass('Hide'); $(this).addClass('xian'); } }else{ if ($(this).hasClass('xian')) { $(this).removeClass('xian'); $(this).addClass('Hide'); } } }); } function handleDivsan(erjiID) {//用来处理点击左側二级菜单后 显示横向相应三级菜单 var temp = "s" + erjiID; //依据二级id拼接成三级div的id 这是自己的约定 $('.main_content #parentchild >div').each(function () {//遍历处理隐藏的三级菜单 if($(this).attr("id")==temp){ if ($(this).hasClass('Hide')) { $(this).removeClass('Hide'); $(this).addClass('xian'); } }else{ if ($(this).hasClass('xian')) { $(this).removeClass('xian'); $(this).addClass('Hide'); } } }); temp = "r" + erjiID; $('.main_content #parentchild .clearfix li').each(function (){//遍历处理横向二级样式 if($(this).attr("id")==temp){ $(this).addClass('on').siblings().removeClass('on'); } }); } function TabOne(){ var oTLi1=$('.main_content #parentchild .mc_tab li'); var oTUl1=$('.mc_one .mc_content'); oTLi1.click(function(){ var _this=$(this); var oI=oTLi1.index(_this); oTLi1.eq(oI).addClass('on').siblings().removeClass('on'); document.getElementById('mulusecond').innerHTML=$(this).text(); loadDatabyID($(this).attr("id").replace("r","")); var temp = $(this).attr("id").replace("r","s"); //依据二级id拼接成三级div的id 这是自己的约定 $('.main_content #parentchild >div').each(function () {//遍历处理隐藏的三级菜单 if($(this).attr("id")==temp){ if ($(this).hasClass('Hide')) { $(this).removeClass('Hide'); $(this).addClass('xian'); } }else{ if ($(this).hasClass('xian')) { $(this).removeClass('xian'); $(this).addClass('Hide'); } } }); }) </script> <script type="text/javascript"> function SetWinHeight(obj) { var win=obj; if (document.getElementById("iframepage")) { if (win && !window.opera) { if (win.contentDocument && win.contentDocument.body.offsetHeight) { win.height = win.contentDocument.body.offsetHeight + 25; } else if(win.Document && win.Document.body.scrollHeight) { win.height = win.Document.body.scrollHeight + 25; } } } } function IFrameReSizeWidth(obj) { var win=obj; if (document.getElementById("iframepage")) { if (win && !window.opera) { if (win.contentDocument && win.contentDocument.body.offsetWidth) { win.width = win.contentDocument.body.offsetWidth; } else if(win.Document && win.Document.body.scrollWidth) { win.width = win.Document.body.scrollWidth; } } } } } </script> </body> </html>
ServiceLeftMenu类用来处理左側菜单请求
public List<MenuModel> getLeftMenu(HttpServletRequest request, HttpServletResponse response) { response.setContentType("text/html;charset=gbk"); response.setCharacterEncoding("gbk");// 防止弹出的信息出现乱码 // 设定查询条件部分省略,menuInfo // 对ID进行切割处理 ids = new String[3]; if ("fenlei".equals(type)) { if (id.contains("-")) { ids = id.split("-"); } else { ids[0] = id; } } // 依据一级菜单parent_id=0,获取一级菜单列表 List<MenuModel> list = new ArrayList<MenuModel>(); menuInfo.setTypeParentId("0"); list = MenuDAO.getMenuList(menuInfo); for (int i = 0; i < list.size(); i++) { MenuModel MenuModel = list.get(i); // 依据二级菜单的parent_id=一级菜单的ID,获取二级菜单列表, menuInfo.setTypeParentId(MenuModel.getTypeId()); // 将二级菜单的列表作为一级菜单的属性保持,这样二级菜单与相应的一级菜单绑定 list.get(i).setChilds(MenuDAO.getMenuList(menuInfo)) ; } // 将一级二级才当列表与前端的样式一起拼接为字符串返回到页面 String strMenu = createMenuByList(list); request.setAttribute("strMenu", strMenu); return null; } private String createMenuByList(List<MenuModel> menulist){ StringBuffer strMenu = new StringBuffer(); strMenu.append("<p><img src='http://img.test.com/images/zhizhen.png' alt='' title=''/>菜单</p>"); for (MenuModel MenuModel : menulist) { //分类页遍历一级菜单 if("fenlei".equals(type)){ strMenu.append("<ul ><li id='"); strMenu.append(MenuModel.getTypeId()); if(MenuModel.getTypeId().equals(ids[0])){ strMenu.append("' class='nav_title'><em class='on'></em>"); strMenu.append(MenuModel.getTypeName()); strMenu.append("</li><li class='nav_details'><ul>"); }else{ strMenu.append("' class='nav_title'><em ></em>"); strMenu.append(MenuModel.getTypeName()); strMenu.append("</li><li class='nav_details dis'><ul>"); } int k = 0; //分类页遍历二级菜单 for (MenuModel child : MenuModel.getChilds()) { if (ids[1] != null && !ids[1].equals("")) { if(child.getTypeId().equals(ids[1])){ strMenu.append("<li class='on' onclick='showSanji("+child.getTypeId()+")'><a class='clearfix'><span>"); }else{ strMenu.append("<li onclick='showSanji("+child.getTypeId()+")'><a class='clearfix'><span>"); } } else { if (k == 0 && ids[0].equals(MenuModel.getTypeId())) { strMenu.append("<li class='on' onclick='showSanji("+child.getTypeId()+")'><a class='clearfix'><span>"); k = 2; } else { strMenu.append("<li onclick='showSanji("+child.getTypeId()+")'><a class='clearfix'><span>"); } } strMenu.append(child.getTypeName()); strMenu.append("</span><em>></em></a></li>"); } strMenu.append("</ul></li></ul>"); } else { //.... } } return strMenu.toString(); }
leftmenu.jsp
<html> <!-- 省略首部内容 --> <head> <script type="text/javascript"> $(document).ready(function(){ Vnavl(); //tab标签 TabOne(); // 顶部文件夹 creatMulu(); <% String id = (String)request.getAttribute("idd"); String[] ids = new String[3]; if (id.contains("-")) { ids = id.split("-"); } else { ids[0] = id; ids[1] = "0"; } %> getChild(<%=ids[0]%>,<%=ids[1]%>);//横向菜单默认打开第一个 }); function creatMulu(){ //刚进入页面依据样式确定一级文件夹的内容 $(".v_nav>ul .nav_title").each(function () { if ($(this).find('em').hasClass('on')) { window.parent.document.getElementById('mulufirst').innerHTML=$(this).text(); } }); //刚进入页面依据样式确定二级文件夹的内容 $('.nav_details>ul>li').each(function () { if ($(this).hasClass('on')) { window.parent.document.getElementById('mulusecond').innerHTML=$(this).text().replace(">",""); } }); } //左側菜单效果 function Vnavl(){ var oUl=$('.v_nav>ul'); var oNavT=$(".v_nav>ul .nav_title"); var oLi=$('.nav_details>ul>li'); oNavT.click(function(){ var _this=$(this); //alert($(this).text()); //alert($(this).attr("id")); var oI=oNavT.index(_this); oNavT.find('em').removeClass('on'); oUl.eq(oI).siblings().find('.nav_details').slideUp(); oUl.eq(oI).find('.nav_details').slideDown(); oNavT.eq(oI).find('em').addClass('on'); var yijiId = $(this).attr("id"); // alert($(this).attr("id")); getChild($(this).attr("id")); var count = 0; oUl.eq(oI).find('.nav_details').find('ul').find('li').each(function () { if(count==0){ $(this).addClass('on'); window.parent.document.getElementById("mulusecond").innerHTML=$(this).text().replace(">",""); parent.loadDatabyID(yijiId); count = 1; } }); //动态改动一级文件夹 window.parent.document.getElementById('mulufirst').innerHTML=$(this).text(); }) oLi.click(function(){ var _this=$(this); var oI=oLi.index(_this); oLi.removeClass('on'); oLi.eq(oI).addClass('on'); //动态改动二级级文件夹 window.parent.document.getElementById('mulusecond').innerHTML=$(this).text().replace(">",""); }) } function showSanji(erjiID){ parent.handleDivsan(erjiID); parent.loadDatabyID(erjiID); } //依据一级菜单ID获得横向二级菜单和三级菜单 function getChild(topid,secondid){ jQuery.ajax({ type: "post", url: "/xf/makesecond.html", data:{param:"child",optionValue:topid,seId:secondid}, success: function(data){ var tt = ""; var default_id = "";//记录二级菜单第一项id var json = eval(data); //数组 $.each(json, function (index) { //循环获取数据 default_id = json[index].firstErjiID; tt = json[index].erjihtml; }); window.parent.document.getElementById('parentchild').innerHTML=tt; parent.queryDataByID(default_id); parent.TabOne(); } }); } </script> </head> <body class="tf"> <div class="v_nav" > <!-- 显示左側菜单 --> <%=request.getAttribute("strMenu") %> </div> </body> </html>
RightMenuService用来查询右側菜单,用json格式返回。通过显示/隐藏样式来控制三级菜单的样式
public List<MenuModel> getMenuRows(HttpServletRequest request, HttpServletResponse response) { // 设置编码 response.setContentType("text/html;charset=gb2312"); response.setCharacterEncoding("gb2312"); // 接受參数 String param = request.getParameter("param"); String optionValue = request.getParameter("optionValue"); String seId = request.getParameter("seId"); // 设定SQL查询条件省略,menuInfo // 查询二级栏目 List<MenuModel> listErji = new ArrayList<MenuModel>(); // 查询三级栏目 List<MenuModel> listSanji = new ArrayList<MenuModel>(); // 横向二级菜单 listErji.clear(); if("child".equals(param)){ menuInfo.setTypeId(optionValue); menuInfo.setFlag("2"); listErji = MenuDAO.getMenuRowsList(menuInfo); request.setAttribute("type_id", optionValue); } String data = "<ul class='clearfix mc_tab'>"; String firstErjiID = ""; int k = 0; for (int i = 0; i < listErji.size(); i++) { String id = "r"+listErji.get(i).getTypeId(); String name = listErji.get(i).getTypeName(); //if (i == 0) { if(listErji.get(i).getTypeId().equals(seId)) { firstErjiID = id; data += "<li class='on' id="+id+">"+name+"</li>"; } else if (("0".equals(seId) && k == 0) || (null ==seId && k == 0)){ // 訪问一级分类或者点击一级分类时默认选择第一个二级分类 k = 1; data += "<li class='on' id="+id+">"+name+"</li>"; } else { data += "<li id="+id+">"+name+"</li>"; } } data += "</ul>"; // 横向三级菜单 listSanji.clear(); for (int i = 0; i < listErji.size(); i++) { menuInfo.setTypeId(listErji.get(i).getTypeId()); menuInfo.setFlag("3"); listSanji = MenuDAO.getMenuRowsList(menuInfo); data +="<div id='s"+listErji.get(i).getTypeId()+"' class='Hide clearfix'><a class='on' onclick='loadDatabyID("+listErji.get(i).getTypeId()+");switchSanjiClass(this)'>所有</a>"; for (int j = 0; j < listSanji.size(); j++) { data += "<a onclick='loadDatabyID("+listSanji.get(j).getTypeId()+");switchSanjiClass(this)'>"+listSanji.get(j).getTypeName()+"</a>"; } data += "</div>"; } //data返回的是json类型的数据 data = "[{\"firstErjiID\":\""+firstErjiID+"\",\"erjihtml\":\""+data+"\"}]"; try { response.getWriter().write(data); } catch (IOException e) { e.printStackTrace(); } return null; }
大致步骤如上。有了新的思路可继续完好哈
补充:实现菜单眼下有两种思路。一是在后端拼接好字符串直接返回,而是在后端返回一个json格式的数据,拼接过程在前端实现。这里补充另外一种方式~
//获得一级菜单 function getTopMenu(){ jQuery("#parent").empty(); jQuery("#parent").append("<p><img src='http://img.test.com/images/zhizhen.png' alt='' title=''/> 菜单</p>"); jQuery.ajax({ type: "post", url: "/xf/makesecond.html", data:{param:"parent"}, success: function(data){ var json = eval(data); //数组 $.each(json, function (index) { //循环获取数据 class="on" var Id = json[index].typeId; var Name = json[index].typeName; if(0==index){ firsetId = Id; jQuery("#parent").append("<ul ><li class='nav_title' onclick='Vnavl()'><em class='on'></em>"+Name+"</li><li class='nav_details'><ul id='"+Id+"'></ul></li></ul>"); } else { jQuery("#parent").append("<ul><li class='nav_title' onclick='Vnavl()' ><em></em>"+Name+"</li><li class='nav_details dis'><ul id='"+Id+"'></ul></li></ul>"); } getChild(Id); }); } }); }
后台实现
public List<MenuModel> getLeftMenu(HttpServletRequest request, HttpServletResponse response) { response.setContentType("text/html;charset=gb2312"); response.setCharacterEncoding("gb2312");// 防止弹出的信息出现乱码 //查询条件省略 List<MenuModel> list = new ArrayList<MenuModel>(); String param = request.getParameter("param"); String optionValue = request.getParameter("optionValue"); list.clear(); if ("parent".equals(param)) { menuInfo.setTypeParentId("0"); list = menuDAO.getLeftMenuList(menuInfo); request.setAttribute("type_id", 0); } else if ("child".equals(param)) { menuInfo.setTypeParentId(optionValue); list = menuDAO.getLeftMenuList(menuInfo); request.setAttribute("type_id", optionValue); } net.sf.json.JSONArray jsonArray = net.sf.json.JSONArray.fromObject(list); String data = jsonArray.toString(); System.out.println(data); try { response.getWriter().write(data); } catch (IOException e) { e.printStackTrace(); } return null; }
右下側数据列表,就是普通的数据展示。依据菜单ID查询相应的数据,进行分页展示。