簡要介紹:
之前手頭的一個項目需要去做一個左側的樹形菜單,右側則是一個整體的iframe,從而構成一個整體的網站。一開始是打算用bootstrap的tree-view插件,直接把菜單的數據傳過去就好了,結果后來項目又改了需求,菜單的內容和圖表都是后臺動態生成的,所以只能放棄使用bootstrap插件,自己著手寫了一個樹形菜單。本文主要分兩部分講,一個是對于bootstrap的treeview的實踐,另一部分是介紹自己寫的樹形菜單。
bootstrap-treeview:
組件介紹://m.survivalescaperooms.com/article/96222.htm
其實關于該組件在其他網站上已經講得很詳細了,我就不再贅述了,但是網上的應用還是有點問題,這里主要講一下自己使用這個插件過程吧。
1. html引用及結構
引用css:文件本身的css文件、bootstrp.css文件
引用js:jquery、bootstrap-treeview.js、引用該組件的treeview.js文件
整體HTML結構主要分為了三個部分:頭部、樹狀欄部分、iframe部分,使用組件的為樹狀欄部分:#tree

2.引用組件js設置:
具體設置代碼如下:主要思路是用data傳入菜單的數據和依靠關系,同時可以設置一些變量來控制改樹狀欄的樣式和基本功能,如代碼40-43行,具體變量對應的數值的意義可以參見之前鏈接中的表格
(function(win) { var data = [ { text: "Parent 1", nodes: [ { text: "Child 1", nodes: [ { text: "Grandchild 1" }, { text: "Grandchild 2" } ] }, { text: "Child 2" } ] }, { text: "Parent 2" }, { text: "Parent 3" }, { text: "Parent 4" }, { text: "Parent 5" } ]; var tree = function() { $('#tree').treeview({ data: data, backColor: '#293541', color: 'white', onhoverColor:'#202a33;', showBorder: false }); } var init = function() { tree(); } init();})(window)設置完成之后樹狀欄的樣式如下圖所示,另外細節方面可以通過閱讀相應參數來設置,值得一提的是樹狀欄的icon圖標是通過bootstrap的glyphicon設置的,有興趣的童鞋可以去看一下這個東西,來為菜單設置不同的icon,不過實際效果感覺不是特別好。這也是我決定自己去搞一個樹狀欄的原因。
自定義樹狀菜單:
treeview的插件只能點擊菜單前面的加號icon展開關閉,樣式的變化有限,而且我們需要根據后臺傳入的數據來動態設置菜單的結構和內容,所以為了滿足這幾個需求,重新寫了一個tree.js
js主要分成三個部分,第一個部分是為每個菜單和子菜單注冊點擊事件以及通過后臺傳來的數據為其綁定跳轉鏈接;第二個部分是通過ajax獲取后臺傳來的菜單數據,并將數據傳入前臺;第三個部分是通過underscore的template函數將前臺頁面進行渲染,達到動態實現樹狀欄的功能。、
相關js代碼:
var tree = function() { //一級導航點擊事件 $('.nodeBox').on('click', function(event) { var _this = $(this); var child = _this.parent().find('.nodechild_box'); if (_this.attr('opened') == 'opened') { _this.parent().find('.childnode').hide(); child.hide(); _this.attr('opened', ''); }else{ _this.parent().find('.childnode').show(); child.show(); _this.attr('opened', 'opened'); }; }); //二級導航點擊事件 $('.nodechild_box').on('click', function(event) { var _this = $(this); var child = _this.parent().find('.gchild_box'); if (_this.attr('opened') == 'opened') { child.hide(); _this.parent().find('.gchildnode').hide(); _this.find('.add').attr('src', 'images/icon_add.png'); _this.attr('opened', ''); }else{ child.show(); _this.parent().find('.gchildnode').show(); _this.find('.add').attr('src', 'images/icon_minus.png'); _this.attr('opened', 'opened'); }; }); //三級導航點擊事件 $('.gchild_box').on('click', function(event) { var _this = $(this); var child = _this.parent().find('.ggchild_box'); if (_this.attr('opened') == 'opened') { child.hide(); _this.find('.add').attr('src', 'images/icon_add.png'); _this.attr('opened', ''); }else{ child.show(); _this.find('.add').attr('src', 'images/icon_minus.png'); _this.attr('opened', 'opened'); }; }); //hover顯示箭頭及背景變化 $('.nodeBox').mouseover(function(event) { $(this).addClass('tree_hover'); $(this).find('.arrow').show(); }); $('.nodeBox').mouseout(function(event) { $(this).removeClass('tree_hover'); $(this).find('.arrow').hide(); }); $('.nodechild_box').mouseover(function(event) { $(this).addClass('box_hover'); $(this).find('.arrow').show(); }); $('.nodechild_box').mouseout(function(event) { $(this).removeClass('box_hover'); $(this).find('.arrow').hide(); }); $('.gchild_box').mouseover(function(event) { $(this).addClass('box_hover'); $(this).find('.arrow').show(); }); $('.gchild_box').mouseout(function(event) { $(this).removeClass('box_hover'); $(this).find('.arrow').hide(); }); $('.ggchild_box').mouseover(function(event) { $(this).addClass('box_hover'); $(this).find('.arrow').show(); }); $('.ggchild_box').mouseout(function(event) { $(this).removeClass('box_hover'); $(this).find('.arrow').hide(); }); }; //鏈接函數 var tree_link = function() { var linkBox = $('[menurl]'); linkBox.each(function(i, ele) { var _ele = $(ele); var key = _ele.attr('menurl'); if(key != '/'){ $(this).on('click',function(){ $('#mainweb').attr('src', key); auto(); }) } }); }; //獲取登陸用戶數據 var getData = function() { var cond = sessionStorage.cond; $.post("XXXX", {}, function(json) { console.log(json) if(json.code == 200){ data = json.data; fillUserName(data); fillTree(data); var length = $('.nodeBox').length ; for (var i = 0;i < length;i++) { var iconId = data.icons[i].iconId; $('.nodeBox').eq(i+1).attr('menuid',i); $('.nodeBox').eq(i+1).find('img').attr('src','images/'+ data.icons[iconId-1].name +''); } //為每個菜單添加鏈接 tree_link() } }, function(xhr) { console.log(xhr) }); } var fillTree = function(data){ var tmplDom = $('#tree'); tmplDom.parent().html(eking.template.getHtml(tmplDom.html(),data)); tree(); }HTML渲染:
<div class="main w_1200"> <div class="tree"> <script type="text/html" id="tree"> <div class="tree_box"> <div class="nodeBox index" menurl="notice.html"> <span class="m_l_10"><img src="images/icon_home.png" alt=""></span> <span class="m_l_10">首頁</span> <span class="arrow fr m_r_10"><img src="images/icon_arrow.png" alt=""></span> </div> </div> <%var menus = data.menus;%> <%for(var i = 0;i < menus.length;i++){%> <div class="tree_box"> <div class="nodeBox" menurl=<%=menus[i].url%> > <span class="m_l_10"><img src="" alt=""></span> <span class="m_l_10"><%=menus[i].name%></span> </div> <%var childmenus = menus[i].childs;%> <%for(var j = 0;j < childmenus.length;j++){%> <div class="childnode"> <div class="nodechild_box" menurl=<%=childmenus[j].url%> > <%if(childmenus[j].childs.length != 0){%> <span class="m_l_20"><img class="add" src="images/icon_add.png" alt=""></span> <span class="m_l_10"><%=childmenus[j].name%></span> <%}else{%> <span class="m_l_55"><%=childmenus[j].name%></span> <span class="arrow fr m_r_10"><img src="images/icon_arrow.png" alt=""></span> <%}%> </div> <%var cchildmenus = childmenus[j].childs;%> <%for(var k = 0;k < cchildmenus.length;k++){%> <div class="gchildnode"> <div class="gchild_box" menurl=<%=cchildmenus[k].url%> > <%if(cchildmenus[k].childs.length != 0){%> <span class="m_l_30"><img class="add" src="images/icon_add.png" alt=""></span> <span class="m_l_10"><%=cchildmenus[k].name%></span> <%}else{%> <span class="m_l_65"><%=cchildmenus[k].name%></span> <span class="arrow fr m_r_10"><img src="images/icon_arrow.png" alt=""></span> <%}%> </div> <%var ccchildmenus = cchildmenus[k].childs;%> <%for(var l = 0;l < ccchildmenus.length;l++){%> <div class="ggchild_box" menurl=<%=ccchildmenus[l].url%> > <span class="m_l_70"><%=ccchildmenus[l].name%></span> <span class="arrow fr m_r_10"><img src="images/icon_arrow.png" alt=""></span> </div> <%}%> </div> <%}%> </div> <%}%> </div> <%}%> </script> </div>后臺傳入的數據格式為

菜單效果如圖:

存在的不足和問題:
為了跟上項目進度,tree.js尚未組件化,等有時間了打算把這一塊封裝為一個js組件,通過設置參數完成樹狀欄的設置。
P.S.由于個人技術水平有限,難免出現錯誤,請多多指正 :)
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。
新聞熱點
疑難解答