現在,我要實現這樣一個功能,
1. 根據數據庫的配置,動態生成橫向導航菜單,如下圖所示:

2. 點擊橫向導航菜單的時候,再動態生成左側菜單。

現在,我是這樣實現的,在系統登錄進來的時候,初始化橫向導航菜單,並用橫向菜單的第一個項(id=1)來初始化左菜單。初始化的過程是用ajax傳遞id=1到后台,然后查詢到id=1的所有子菜單,以xml的形式返回給前台。然后前台解析xml生成左菜單。
登錄進來之后,點擊橫向菜單按鈕,執行的也是上面的這段邏輯。
現在遇到的問題是:一開始登錄進來初始化的時候,沒什么問題;但之后點擊橫向導航的時候,就出現問題了,左側菜單樹(tree)的樣式就沒有了,導致菜單沒辦法使用。如下圖所示

出現該問題的具體原因如下:
<div id="accordion" class="accordion" fillSpace="sidebar"> </div>
DWZ初始化加載這個組件的時候,使用的是(function($){})(jQuery);(即初始化執行一次)這種方式,在js代碼中初始化各個元素的樣式和綁定事件(而不是通過CSS來進行初始化)。這種情況下,在一次刷新頁面過程中,樣式只執行一次加載,如果要重新加載樣式,必須要重新刷新頁面。
這樣就導致在登錄進來之后,再次點擊橫向導航(比如資訊管理)的時候,動態生成的html內容,因為沒有經過初始化js對其進行樣式加載,從而不會出現任何樣式效果。
具體解決方案:
1. 將初始化左菜單樣式的js從(function($){})(jQuery);里面抽取出來,重寫一個js方法fillSpace()。
2. 在動態生成html內容之后,再調用上面的js方法初始化樣式。
具體的實現方式見源碼(index.jsp)
------------------------------------------------------------------------------------------------------------------------------------
具體的代碼我簡單的貼一下,這里只有前台頁面的代碼,后台動態返回結果的代碼,是struts2的,暫時不提供了,只提供最終返回的JSON數據
<%@ page contentType="text/html; charset=UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags"%> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=8" /> <title>EMBoss</title> <link href="themes/default/style.css" rel="stylesheet" type="text/css" media="screen"/> <link href="themes/css/core.css" rel="stylesheet" type="text/css" media="screen"/> <link href="themes/css/print.css" rel="stylesheet" type="text/css" media="print"/> <link href="uploadify/css/uploadify.css" rel="stylesheet" type="text/css" media="screen"/> <!--[if IE]> <link href="themes/css/ieHack.css" rel="stylesheet" type="text/css" media="screen"/> <![endif]--> <style type="text/css"> #header{height:85px} #leftside, #container, #splitBar, #splitBarProxy{top:90px} </style> <!--[if lte IE 9]> <script src="js/speedup.js" type="text/javascript"></script> <![endif]--> <script src="js/jquery-1.7.2.min.js" type="text/javascript"></script> <script src="js/jquery.cookie.js" type="text/javascript"></script> <script src="js/jquery.validate.js" type="text/javascript"></script> <script src="js/jquery.bgiframe.js" type="text/javascript"></script> <script src="xheditor/xheditor-1.2.1.min.js" type="text/javascript"></script> <script src="xheditor/xheditor_lang/zh-cn.js" type="text/javascript"></script> <script src="uploadify/scripts/jquery.uploadify.min.js" type="text/javascript"></script> <script src="bin/dwz.min.js" type="text/javascript"></script> <script src="js/dwz.regional.zh.js" type="text/javascript"></script> <script type="text/javascript"> var ts=""; /* 把xml字符串轉成xml對象 */ function parseXml(xmlStr){ var xml; if($.browser.msie){ xml = new ActiveXObject("Microsoft.XMLDOM"); xml.async = false; xml.loadXML(xmlStr); }else{ xml = new DOMParser().parseFromString(xmlStr, "text/xml"); } return xml; } //設置橫向導航菜單 //通過struts2的action獲取橫向導航的json字符串,data.returnList數據如下: /* Object { tmid=1, tmname="資訊管理"} Object { tmid=2, tmname="訂單管理"} Object { tmid=3, tmname="產品管理"} Object { tmid=4, tmname="會員管理"} Object { tmid=5, tmname="服務管理"} Object { tmid=6, tmname="系統設置"} */ function settopmenu() { $.getJSON("<%=request.getContextPath()%>/menumgr!getTopMenu.action", function(data){ var tm='<ul>'; $.each(data.returnList, function(i,item){ if(i==0){ //selectClass = "selected"; tm+='<li class="selected"><a href="javascript:void(0)" onclick="changeMenu(this,'+item.tmid+')" rel="'+item.tmid+'"><span>'+item.tmname+'</span></a></li>'; }else{ //selectClass = "none"; tm+='<li><a href="javascript:void(0)" onclick="changeMenu(this,'+item.tmid+')" rel="'+item.tmid+'"><span>'+item.tmname+'</span></a></li>'; } //tm+='<li class="'+selectClass+'"><a href="index_menu.jsp?pid='+item.tmid+'"><span>'+item.tmname+'</span></a></li>'; }); tm+="</ul>"; $("#navMenu").html(tm); } ); } //遞歸生成左側菜單樹div function setts(nodes,flag) { for(var i=0;i<nodes.length;i++) { var cnodes=$(nodes[i]).children(); if(cnodes.length==0) { ts+='<li><a href="'+$(nodes[i]).attr("url")+'" target="navTab" rel="'+$(nodes[i]).attr("id")+'">'+$(nodes[i]).attr("name")+'</a></li>'; if((i==nodes.length-1) && (nodes[i].parentNode.nodeName=="treenode") && flag==1) ts+='</ul></li>'; }else { if(nodes[i].parentNode.nodeName=="root"){ ts+='<div class="accordionHeader">'+ '<h2><span>Folder</span>'+$(nodes[i]).attr("name")+'</h2>'+ '</div>'+ '<div class="accordionContent">'+ '<ul class="tree treeFolder">'; //setts(cnodes); }else{ flag = 1; ts+='<li><a href="'+$(nodes[i]).attr("url")+'" target="navTab" rel="'+$(nodes[i]).attr("id")+'">'+$(nodes[i]).attr("name")+'</a>'; ts+='<ul>'; } setts(cnodes,flag); if(nodes[i].parentNode.nodeName=="root") ts+='</ul></div>'; } } } //橫向導航點擊之后的函數調用 //更改點擊之后的按鈕樣式,調用左側菜單樹生成函數 function changeMenu(obj,tmid){ //設置點擊橫向菜單后橫向菜單的樣式 $('#navMenu ul li').each(function(idx){ $('#navMenu ul li').removeClass(); }); $(obj).parent().addClass("selected"); //獲取橫向菜單的所有子菜單,並顯示 getSubMenuClick(tmid); } //初始化左側滑動菜單的樣式 function fillSpace(obj) { if (!obj) return; var parent = $(obj).parent(); var hht = parent.height() - (($(".accordionHeader", obj).size()) * ($(".accordionHeader:first-child", obj).outerHeight())) - 2; var os = parent.children().not(obj); $.each(os, function(i) { hht -= $(os[i]).outerHeight(); }); //設置第一個滑動菜單標題按鈕為打開狀態 $(".accordionHeader h2",obj).eq(0).addClass("collapsable"); //設置所有的滑動菜單內容不可見 $(".accordionContent",obj).css({ display:"none", height:hht }); //設置第一個滑動菜單內容為可見狀態 $(".accordionContent",obj).eq(0).css({ display:"block", height:hht }); //第一個滑動菜單標題按鈕默認為已點擊狀態 $(".accordionHeader h2",obj).eq(0).click(); } //頁面第一次加載的時候,初始化左菜單樹,不需要加載樣式,同getSubMenuClick方法 //調用struts2的action查詢tmid的子菜單,以xml返回結果,data.returnString屬性的xml格式如下: /* <?xml version="1.0" encoding="UTF-8"?><root><treenode id="102" name="界面組件"><treenode id="1021" name="主框架面板" url="demo_page4.html"/><treenode id="1022" name="主框架面板" url="demo_page4.html"/></treenode><treenode id="103" name="界面組件"><treenode id="1031" name="主框架面板2" url="demo_page4.html"/></treenode><treenode id="104" name="界面組件"><treenode id="1041" name="主框架面板3" url="demo_page4.html"/></treenode><treenode id="101" name="界面組件"><treenode id="1012" name="主框架面板2"><treenode id="10121" name="子菜單" url="demo_page4.html"/><treenode id="10122" name="子菜單" url="demo_page4.html"/></treenode><treenode id="1011" name="主框架面板"><treenode id="10112" name="我的主頁2" url="demo_page4.html"/><treenode id="10113" name="我的主頁3" url="demo_page4.html"/><treenode id="10111" name="我的主頁1" url="demo_page4.html"/></treenode></treenode></root> */ function getSubMenu(tmid) { $.ajax({ type: "GET", /menumgr!getMenuTree.action'">url:'<%=request.getContextPath()%>/menumgr!getMenuTree.action', data:{ pid:tmid }, dataType:"json", cache: false, success: function(data){ ts=""; var nodes=$("root>treenode",parseXml(data.returnString)); setts(nodes,0); $("#loading").show(); $("#accordion").html(ts); $("#loading").hide(); } }); } //點擊橫向導航菜單的時候,動態加載左菜單樹,需要加載樣式 function getSubMenuClick(tmid) { $.ajax({ type: "GET", /menumgr!getMenuTree.action'">url:'<%=request.getContextPath()%>/menumgr!getMenuTree.action', data:{ pid:tmid }, dataType:"json", cache: false, success: function(data){ ts=""; var nodes=$("root>treenode",parseXml(data.returnString)); setts(nodes,0); $("#loading").show(); $("#accordion").html(ts); $("#loading").hide(); //以下三項初始化左菜單樣式 fillSpace($("#accordion")); initLayout(); initUI(); } }); } } //DWZ初始化 function dwzInit(){ DWZ.init("dwz.frag.xml", { loginUrl:"login_dialog.html", loginTitle:"登錄", // 彈出登錄對話框 // loginUrl:"login.html", // 跳到登錄頁面 statusCode:{ok:200, error:300, timeout:301}, //【可選】 pageInfo:{pageNum:"pageNum", numPerPage:"numPerPage", orderField:"orderField", orderDirection:"orderDirection"}, //【可選】 debug:false, // 調試模式 【true|false】 callback:function(){ initEnv(); $("#themeList").theme({themeBase:"themes"}); //setTimeout(function() {$("#sidebar .toggleCollapse div").trigger("click");}, 10); } }); } //頁面加載后初始化所有元素,包含初始化第一個橫向導航的子菜單(左菜單樹) $(function(){ //設置頂部菜單 settopmenu(); //設置默認菜單列表 getSubMenu(1); dwzInit(); }); </script> </head> <body scroll="no"> <div id="layout"> <div id="header"> <div class="headerNav"> <a class="logo" href="o'>http://j-ui.com">o標志</a> <ul class="nav"> <li id="switchEnvBox"><a href="javascript:">(<span>北京</span>)切換城市</a> <ul> <li><a href="sidebar_1.html">北京</a></li> <li><a href="sidebar_2.html">上海</a></li> <li><a href="sidebar_2.html">南京</a></li> <li><a href="sidebar_2.html">深圳</a></li> <li><a href="sidebar_2.html">廣州</a></li> <li><a href="sidebar_2.html">天津</a></li> <li><a href="sidebar_2.html">杭州</a></li> </ul> </li> <li><a href="https://me.alipay.com/dwzteam" target="_blank">捐贈</a></li> <li><a href="changepwd.html" target="dialog" width="600">設置</a></li> <li><a href="http://www.cnblogs.com/dwzjs" target="_blank">博客</a></li> <li><a href="http://weibo.com/dwzui" target="_blank">微博</a></li> <li><a href="http://bbs.dwzjs.com" target="_blank">論壇</a></li> <li><a href="login.html">退出</a></li> </ul> <ul class="themeList" id="themeList"> <li theme="default"> <div class="selected">藍色</div> </li> <li theme="green"> <div>綠色</div> </li> <!--<li theme="red"><div>紅色</div></li>--> <li theme="purple"> <div>紫色</div> </li> <li theme="silver"> <div>銀色</div> </li> <li theme="azure"> <div>天藍</div> </li> </ul> </div> <div id="navMenu"> </div> </div> <div id="leftside"> <div id="sidebar_s"> <div class="collapse"> <div class="toggleCollapse"> <div></div> </div> </div> </div> <div id="sidebar"> <div id="loading" style="color:#ff0000;">Loading....</div> <div class="toggleCollapse"> <h2>主菜單</h2> <div>收縮</div> </div> <div id="accordion" class="accordion" fillSpace="sidebar"> </div> </div> </div> <div id="container"> <div id="navTab" class="tabsPage"> <div class="tabsPageHeader"> <div class="tabsPageHeaderContent"> <!-- 顯示左右控制時添加 class="tabsPageHeaderMargin" --> <ul class="navTab-tab"> <li tabid="main" class="main"><a href="javascript:;"><span><span class="home_icon">我的主頁</span></span></a></li> </ul> </div> <div class="tabsLeft">left</div> <!-- 禁用只需要添加一個樣式 class="tabsLeft tabsLeftDisabled" --> <div class="tabsRight">right</div> <!-- 禁用只需要添加一個樣式 class="tabsRight tabsRightDisabled" --> <div class="tabsMore">more</div> </div> <ul class="tabsMoreList"> <li><a href="javascript:;">我的主頁</a></li> </ul> <div class="navTab-panel tabsPageContent layoutBox"> <div class="page unitBox"> <div class="accountInfo"> <div class="alertInfo"> <h2><a href="doc/dwz-user-guide.pdf" target="_blank">DWZ框架使用手冊(PDF)</a></h2> <a href="doc/dwz-user-guide.swf" target="_blank">DWZ框架演示視頻</a> </div> <div class="right"> <p><a href="doc/dwz-user-guide.zip" target="_blank" style="line-height:19px">DWZ框架使用手冊(CHM)</a></p> <p><a href="doc/dwz-ajax-develop.swf" target="_blank" style="line-height:19px">DWZ框架Ajax開發視頻教材</a></p> </div> <p><span>DWZ富客戶端框架</span></p> <p>DWZ官方微博:<a href="http://weibo.com/dwzui" target="_blank">http://weibo.com/dwzui</a></p> </div> <div class="pageFormContent" layoutH="80"> </div> </div> </div> </div> </div> </div> <div id="footer">Copyright © 2010 <a href="demo_page2.html" target="dialog">DWZ團隊</a></div> </body> </html>
問題已經解決,解決方法見下面的紅色粗體字體部分
------------------------------------------------------------------------------
3. 橫向導航點擊之后的函數調用如下:
//更改點擊之后的按鈕樣式,調用左側菜單樹生成函數
function changeMenu(obj,tmid){ $('#navMenu ul li').each(function(idx){ $('#navMenu ul li').removeClass(); }); $(obj).parent().addClass("selected");
//再次執行DWZ初始化方法,否則重新加載的菜單樹會丟失樣式 dwzInit(); //設置默認菜單列表 getSubMenu(tmid); }
--------------------------------------------------------------------------------------
另外,在測試的過程中發現,在IE中運行這個程序時,點擊橫向導航后,出現數據加載中提示,一直無法去掉

參照網上的說明處理如下:
-----
我發現官網給的index.jsp里面<meta http-equiv="X-UA-Compatible" content="IE=7" />,就是說文檔的格式是IE7標准,
后來我這樣的解決的,把這個文檔標准換成了IE8,即:<meta http-equiv="X-UA-Compatible" content="IE=8" />,
然后再IE下面就不出現這個問題了。。。。
問題補充:
console.log('');今天又發現了一個問題,在IE下,又出現了上面的這個問題,調試了半天,原來是js里面console.log(''); 的問題,把它去掉就行了。。
-----
希望對大家有幫助。
哎,杯具一個接着一個,測試的時候,又發現雖然有樣式了,但菜單樹默認情況下是全打開的,而且左側沒有完全縱向展開,如下所示:
正常: 不正常:


已解決,核心代碼是:
增加一個JS方法:
//初始化左側滑動菜單的樣式 function fillSpace(obj) { if (!obj) return; var parent = $(obj).parent(); var hht = parent.height() - (($(".accordionHeader", obj).size()) * ($(".accordionHeader:first-child", obj).outerHeight())) - 2; var os = parent.children().not(obj); $.each(os, function(i) { hht -= $(os[i]).outerHeight(); }); //設置第一個滑動菜單標題按鈕為打開狀態 $(".accordionHeader h2",obj).eq(0).addClass("collapsable"); //設置所有的滑動菜單內容不可見 $(".accordionContent",obj).css({ display:"none", height:hht }); //設置第一個滑動菜單內容為可見狀態 $(".accordionContent",obj).eq(0).css({ display:"block", height:hht }); //第一個滑動菜單標題按鈕默認為已點擊狀態 $(".accordionHeader h2",obj).eq(0).click(); }
如果在界面中使用了$("#accordion").html(ts);這種方式動態生成界面,必須要重新執行js生成樣式代碼,DWZ初始化的時候,有兩個初始化方法我們可以直接調用:
initLayout(); initUI();
如果執行這兩個方法之后,還有問題,那么只能具體原因具體分析,再去根據源碼重新加載相應的組件樣式。
上面新增的這個方法是專門針對左側滑動菜單樹的樣式重新加載方法。
在此感謝 王海峰 提供。