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 οnlοad="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" οnlοad="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' οnclick='showSanji("+child.getTypeId()+")'><a class='clearfix'><span>");
}else{
strMenu.append("<li οnclick='showSanji("+child.getTypeId()+")'><a class='clearfix'><span>");
}
} else {
if (k == 0 && ids[0].equals(MenuModel.getTypeId())) {
strMenu.append("<li class='on' οnclick='showSanji("+child.getTypeId()+")'><a class='clearfix'><span>");
k = 2;
} else {
strMenu.append("<li οnclick='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' οnclick='loadDatabyID("+listErji.get(i).getTypeId()+");switchSanjiClass(this)'>全部</a>";
for (int j = 0; j < listSanji.size(); j++) {
data += "<a οnclick='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' οnclick='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' οnclick='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查询对应的数据,进行分页展示。