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" ></span>
 7                     <span class="m_l_10">首页</span>
 8                     <span class="arrow fr m_r_10"><img src="images/icon_arrow.png" ></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="" ></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" ></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" ></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" ></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" ></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" ></span>
47                         </div>
48                         <%}%>
49                     </div>
50                     <%}%>
51                 </div>
52                 <%}%>
53             </div>
54         <%}%>
55         </script>
56         </div>

  后台传入的数据格式为

  

  菜单效果如图:

  

  存在的不足和问题

  为了跟上项目进度,tree.js尚未组件化,等有时间了打算把这一块封装为一个js组件,通过设置参数完成树状栏的设置。

  P.S.由于个人技术水平有限,难免出现错误,请多多指正 :)

时间: 2024-11-08 14:23:31

treeview-树形菜单js组件编写及应用的相关文章

mvc中的树形菜单 js

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %> <!DOCTYPE html> <html> <head runat="server"> <title>Index</title> <link href="../../Content/jquery-easyui

JS树形菜单

超全的JS树形菜单源代码共享(有实例图) 树形菜单是很常用的效果,常用在管理软件当中,但是一套树形菜单已经不能满足需求,所以如果能有一套比较全面的树形菜单JS特效代码,将会非常方便,下面懒人萱将超全的JS树形菜单共享出来,相信你一定用得上. 一共包括八种,下面就一一介绍: 1.不同表现方式的JS树形菜单(如图所示) 2.复选框式的JS树形菜单(如图所示)左图为只可以选择单节点,右图为在选择子节点的同时选择父节点 3.可以重新排列节点并且具有拖放功能的js树形菜单(如图所示) 4.带有提示框的js

jquery树形菜单

转自:http://keleyi.com/dev/3068696139522ae4.htm 代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"&g

JS组件系列——分享自己封装的Bootstrap树形组件:jqTree

前言:之前的一篇介绍了下如何封装自己的组件,这篇再次来体验下自己封装组件的乐趣.看过博主博客的园友应该记得之前分享过一篇树形菜单的使用JS组件系列——Bootstrap 树控件使用经验分享,这篇里面第一个Jquery Tree,只是用简单样式和js去实现了效果,没有给出一个系统的封装,这篇博主就来试试在此样式的基础上封装一个稍微完整点的树形组件. 一.组件效果预览 其实效果和之前的那个差不多,博主只是在之前的基础上加了一个选中的背景色. 全部收起 展开 全部展开 二.代码示例 其实效果很简单,重

Unity UGUI自定义树形菜单(TreeView)

先上几张效果图:          如果你需要的也是这种效果,那你就来对地方了! 目前,我们这个树形菜单展现出来的功能如下: 1.可以动态配置数据源: 2.点击每个元素的上下文菜单按钮(也就是图中的三角形按钮),可以收缩或展开它的子元素: 3.可以单独判断某一元素的复选框是否被勾选,或者直接获取当前树形菜单中所有被勾选的元素: 4.树形菜单统一控制其下所有子元素按钮的事件分发: 5.可自动调节的滚动视野边缘,根据当前可见的子元素数量进行横向以及纵向的伸缩: 一.首先,我们先制作子元素的模板(Te

java--css+js做的树形菜单(完整版)

jsp页面: <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":"

推酷文章中编写js组件系列文章整理

一步一步实现JS拖拽插件 http://www.tuicool.com/articles/RBbmMjY JS组件系列——基于Bootstrap Ace模板的菜单和Tab页效果分享 http://www.tuicool.com/articles/aiiQFjb

利用多叉树实现Ext JS中的无限级树形菜单(一种构建多级有序树形结构JSON的方法)

一.问题研究的背景和意义 目前在Web应用程序开发领域,Ext JS框架已经逐渐被广泛使用,它是富客户端开发中出类拔萃的框架之一.在Ext的UI控件中,树形控件无疑是最为常用的控件之一,它用来实现树形结构的菜单.TreeNode用来实现静态的树形菜单,AsyncTreeNode用来实现动态的异步加载树形菜单,后者最为常用,它通过接收服务器端返回来的JSON格式的数据,动态生成树形菜单节点.动态生成树有两种思路:一种是一次性生成全部树节点,另一种是逐级加载树节点(利用AJAX,每次点击节点时查询下

JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化

前言:之前发表过一篇  JS组件系列——基于Bootstrap Ace模板的菜单和Tab页效果分享(你值得拥有) ,收到很多园友的反馈,当然也包括很多诟病,因为上篇只是将功能实现了,很多细节都没有处理,这篇博主将带领大家一起来优化这里的效果,使之成为一个可以在项目里面使用的成品. 说点题外话,本来,在互联网模式下,Tab页+iframe的组合是不能被大多数平台接受的,从这些年推出的一些好的产品可以看出,几乎大家都不这么玩,即使是一些后台的管理模板,比如常见的AdminLTE.Ace.INSPIN