treeview-樹形菜單js組件編寫及應用


簡要介紹:  

  之前手頭的一個項目需要去做一個左側的樹形菜單,右側則是一個整體的iframe,從而構成一個整體的網站。一開始是打算用bootstrap的tree-view插件,直接把菜單的數據傳過去就好了,結果后來項目又改了需求,菜單的內容和圖表都是后台動態生成的,所以只能放棄使用bootstrap插件,自己着手寫了一個樹形菜單。本文主要分兩部分講,一個是對於bootstrap的treeview的實踐,另一部分是介紹自己寫的樹形菜單。

 

bootstrap-treeview:

組件介紹http://www.htmleaf.com/jQuery/Menu-Navigation/201502141379.html

  其實關於該組件在其他網站上已經講得很詳細了,我就不再贅述了,但是網上的應用還是有點問題,這里主要講一下自己使用這個插件過程吧。

  1. html引用及結構

  引用css:文件本身的css文件、bootstrp.css文件

  引用js:jquery、bootstrap-treeview.js、引用該組件的treeview.js文件

  整體HTML結構主要分為了三個部分:頭部、樹狀欄部分、iframe部分,使用組件的為樹狀欄部分:#tree

  2.引用組件js設置:

  具體設置代碼如下:主要思路是用data傳入菜單的數據和依靠關系,同時可以設置一些變量來控制改樹狀欄的樣式和基本功能,如代碼40-43行,具體變量對應的數值的意義可以參見之前鏈接中的表格

 1 (function(win) {
 2     
 3         var data = [
 4           {
 5             text: "Parent 1",
 6             nodes: [
 7               {
 8                 text: "Child 1",
 9                 nodes: [
10                   {
11                     text: "Grandchild 1"
12                   },
13                   {
14                     text: "Grandchild 2"
15                   }
16                 ]
17               },
18               {
19                 text: "Child 2"
20               }
21             ]
22           },
23           {
24             text: "Parent 2"
25           },
26           {
27             text: "Parent 3"
28           },
29           {
30             text: "Parent 4"
31           },
32           {
33             text: "Parent 5"
34           }
35         ];          
36     
37     var tree = function() {
38         $('#tree').treeview({
39              data: data,
40               backColor: '#293541',
41               color: 'white',
42               onhoverColor:'#202a33;',
43               showBorder: false
44             });    
45     }
46      
47     var init = function() {
48         tree();
49     }
50     
51     init();
52 })(window)

  設置完成之后樹狀欄的樣式如下圖所示,另外細節方面可以通過閱讀相應參數來設置,值得一提的是樹狀欄的icon圖標是通過bootstrap的glyphicon設置的,有興趣的童鞋可以去看一下這個東西,來為菜單設置不同的icon,不過實際效果感覺不是特別好。這也是我決定自己去搞一個樹狀欄的原因。

 

 

  

  自定義樹狀菜單:

  treeview的插件只能點擊菜單前面的加號icon展開關閉,樣式的變化有限,而且我們需要根據后台傳入的數據來動態設置菜單的結構和內容,所以為了滿足這幾個需求,重新寫了一個tree.js

  js主要分成三個部分,第一個部分是為每個菜單和子菜單注冊點擊事件以及通過后台傳來的數據為其綁定跳轉鏈接;第二個部分是通過ajax獲取后台傳來的菜單數據,並將數據傳入前台;第三個部分是通過underscore的template函數將前台頁面進行渲染,達到動態實現樹狀欄的功能。、

  相關js代碼:

 

  1     var tree = function() {
  2         //一級導航點擊事件
  3         $('.nodeBox').on('click', function(event) {
  4             var _this = $(this);
  5             var child = _this.parent().find('.nodechild_box');
  6             if (_this.attr('opened') == 'opened') {
  7                 _this.parent().find('.childnode').hide();
  8                 child.hide();
  9                 _this.attr('opened', '');
 10             }else{
 11                 _this.parent().find('.childnode').show();
 12                 child.show();
 13                 _this.attr('opened', 'opened');
 14             };
 15         });
 16         //二級導航點擊事件
 17         $('.nodechild_box').on('click', function(event) {
 18             var _this = $(this);
 19             var child = _this.parent().find('.gchild_box');
 20             if (_this.attr('opened') == 'opened') {
 21                 child.hide();
 22                 _this.parent().find('.gchildnode').hide();
 23                 _this.find('.add').attr('src', 'images/icon_add.png');
 24                 _this.attr('opened', '');
 25             }else{
 26                 child.show();
 27                 _this.parent().find('.gchildnode').show();
 28                 _this.find('.add').attr('src', 'images/icon_minus.png');
 29                 _this.attr('opened', 'opened');
 30             };
 31         });
 32         //三級導航點擊事件
 33         $('.gchild_box').on('click', function(event) {
 34             var _this = $(this);
 35             var child = _this.parent().find('.ggchild_box');
 36             if (_this.attr('opened') == 'opened') {
 37                 child.hide();
 38                 _this.find('.add').attr('src', 'images/icon_add.png');
 39                 _this.attr('opened', '');
 40             }else{
 41                 child.show();
 42                 _this.find('.add').attr('src', 'images/icon_minus.png');
 43                 _this.attr('opened', 'opened');
 44             };
 45         });
 46 
 47         //hover顯示箭頭及背景變化
 48         $('.nodeBox').mouseover(function(event) {
 49             $(this).addClass('tree_hover');
 50             $(this).find('.arrow').show();
 51         });
 52         $('.nodeBox').mouseout(function(event) {
 53             $(this).removeClass('tree_hover');
 54             $(this).find('.arrow').hide();
 55         });
 56         $('.nodechild_box').mouseover(function(event) {
 57             $(this).addClass('box_hover');
 58             $(this).find('.arrow').show();
 59         });
 60         $('.nodechild_box').mouseout(function(event) {
 61             $(this).removeClass('box_hover');
 62             $(this).find('.arrow').hide();
 63         });
 64         $('.gchild_box').mouseover(function(event) {
 65             $(this).addClass('box_hover');
 66             $(this).find('.arrow').show();
 67         });
 68         $('.gchild_box').mouseout(function(event) {
 69             $(this).removeClass('box_hover');
 70             $(this).find('.arrow').hide();
 71         });
 72         $('.ggchild_box').mouseover(function(event) {
 73             $(this).addClass('box_hover');
 74             $(this).find('.arrow').show();
 75         });
 76         $('.ggchild_box').mouseout(function(event) {
 77             $(this).removeClass('box_hover');
 78             $(this).find('.arrow').hide();
 79         });
 80     };
 81     
 82     //鏈接函數
 83     var tree_link = function() {
 84         
 85         var linkBox = $('[menurl]');
 86         linkBox.each(function(i, ele) {
 87             var _ele = $(ele);
 88             var key = _ele.attr('menurl');
 89             if(key != '/'){
 90                 $(this).on('click',function(){
 91                     $('#mainweb').attr('src', key);
 92                     auto();
 93                 })    
 94             }
 95             
 96         });
 97     };
 98     
 99     //獲取登陸用戶數據
100     var getData = function() {
101         var cond = sessionStorage.cond; 
102         
103         $.post("XXXX", {}, function(json) {
104             console.log(json)
105             if(json.code == 200){
106                 data = json.data;
107                 fillUserName(data);
108                 fillTree(data);
109                 var length = $('.nodeBox').length ;
110                 for (var i = 0;i < length;i++) {            
111                     var iconId = data.icons[i].iconId;
112                     $('.nodeBox').eq(i+1).attr('menuid',i);
113                     $('.nodeBox').eq(i+1).find('img').attr('src','images/'+ data.icons[iconId-1].name +'');
114 
115                 }
116                 //為每個菜單添加鏈接
117                 tree_link()
118             }
119         }, function(xhr) {
120             console.log(xhr)
121         });
122 
123     }
124     
125     
126     var fillTree = function(data){
127         var tmplDom = $('#tree');
128         tmplDom.parent().html(eking.template.getHtml(tmplDom.html(),data));
129         tree();
130     }

 

  HTML渲染:

 

 

 1     <div class="main w_1200">
 2         <div class="tree">
 3         <script type="text/html" id="tree">
 4             <div class="tree_box">
 5                 <div class="nodeBox index" menurl="notice.html">
 6                     <span class="m_l_10"><img src="images/icon_home.png" alt=""></span>
 7                     <span class="m_l_10">首頁</span>
 8                     <span class="arrow fr m_r_10"><img src="images/icon_arrow.png" alt=""></span>
 9                 </div>
10             </div>
11             <%var menus = data.menus;%>
12             <%for(var i = 0;i < menus.length;i++){%>
13             <div class="tree_box">
14                 <div class="nodeBox" menurl=<%=menus[i].url%> >
15                     <span class="m_l_10"><img src="" alt=""></span>
16                     <span class="m_l_10"><%=menus[i].name%></span>
17                 </div>
18                 <%var childmenus = menus[i].childs;%>
19                 <%for(var j = 0;j < childmenus.length;j++){%>
20                 <div class="childnode">
21                     <div class="nodechild_box" menurl=<%=childmenus[j].url%> >
22                         <%if(childmenus[j].childs.length != 0){%>
23                         <span class="m_l_20"><img class="add" src="images/icon_add.png" alt=""></span>
24                         <span class="m_l_10"><%=childmenus[j].name%></span>
25                         <%}else{%>
26                         <span class="m_l_55"><%=childmenus[j].name%></span>
27                         <span class="arrow fr m_r_10"><img src="images/icon_arrow.png" alt=""></span>
28                         <%}%>
29                     </div>
30                     <%var cchildmenus = childmenus[j].childs;%>
31                     <%for(var k = 0;k < cchildmenus.length;k++){%>
32                     <div class="gchildnode">
33                         <div class="gchild_box" menurl=<%=cchildmenus[k].url%> >
34                             <%if(cchildmenus[k].childs.length != 0){%>
35                             <span class="m_l_30"><img class="add" src="images/icon_add.png" alt=""></span>
36                             <span class="m_l_10"><%=cchildmenus[k].name%></span>
37                             <%}else{%>
38                             <span class="m_l_65"><%=cchildmenus[k].name%></span>
39                             <span class="arrow fr m_r_10"><img src="images/icon_arrow.png" alt=""></span>
40                             <%}%>
41                         </div>
42                         <%var ccchildmenus = cchildmenus[k].childs;%>
43                         <%for(var l = 0;l < ccchildmenus.length;l++){%>
44                         <div class="ggchild_box" menurl=<%=ccchildmenus[l].url%> >
45                             <span class="m_l_70"><%=ccchildmenus[l].name%></span>
46                             <span class="arrow fr m_r_10"><img src="images/icon_arrow.png" alt=""></span>
47                         </div>
48                         <%}%>
49                     </div>
50                     <%}%>
51                 </div>
52                 <%}%>
53             </div>
54         <%}%>
55         </script>
56         </div>

 

  后台傳入的數據格式為

  

  菜單效果如圖:

  

 

   存在的不足和問題

  為了跟上項目進度,tree.js尚未組件化,等有時間了打算把這一塊封裝為一個js組件,通過設置參數完成樹狀欄的設置。

  P.S.由於個人技術水平有限,難免出現錯誤,請多多指正 :)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM