JS树形菜单组件Bootstrap TreeView使用方法详解


Posted in Javascript onDecember 21, 2016

简要介绍:  

之前手头的一个项目需要去做一个左侧的树形菜单,右侧则是一个整体的iframe,从而构成一个整体的网站。一开始是打算用bootstrap的tree-view插件,直接把菜单的数据传过去就好了,结果后来项目又改了需求,菜单的内容和图表都是后台动态生成的,所以只能放弃使用bootstrap插件,自己着手写了一个树形菜单。本文主要分两部分讲,一个是对于bootstrap的treeview的实践,另一部分是介绍自己写的树形菜单。

bootstrap-treeview:

组件介绍:https://3water.com/article/96222.htm

其实关于该组件在其他网站上已经讲得很详细了,我就不再赘述了,但是网上的应用还是有点问题,这里主要讲一下自己使用这个插件过程吧。

1. html引用及结构

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

引用js:jquery、bootstrap-treeview.js、引用该组件的treeview.js文件

整体HTML结构主要分为了三个部分:头部、树状栏部分、iframe部分,使用组件的为树状栏部分:#tree

JS树形菜单组件Bootstrap TreeView使用方法详解

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,不过实际效果感觉不是特别好。这也是我决定自己去搞一个树状栏的原因。

JS树形菜单组件Bootstrap TreeView使用方法详解

自定义树状菜单:

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>

后台传入的数据格式为

JS树形菜单组件Bootstrap TreeView使用方法详解

菜单效果如图:

JS树形菜单组件Bootstrap TreeView使用方法详解

存在的不足和问题:

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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery库与其他JS库冲突的解决办法
Feb 07 Javascript
jquery isEmptyObject判断是否为空对象的函数
Feb 14 Javascript
jQuery判断对象是否存在的方法
Feb 05 Javascript
javascript转换日期字符串为Date日期对象的方法
Feb 13 Javascript
JavaScript脚本库编写的方法
Dec 09 Javascript
jquery之别踩白块游戏的简单实现
Jul 25 Javascript
JS异步函数队列功能实例分析
Nov 28 Javascript
微信小程序实现红包雨功能
Jul 11 Javascript
JS判断两个数组或对象是否相同的方法示例
Feb 28 Javascript
layui实现左侧菜单点击右侧内容区显示
Jul 26 Javascript
Vue基于iview table展示图片实现点击放大
Aug 05 Javascript
vue+openlayers绘制省市边界线
Dec 24 Vue.js
Vue.js 递归组件实现树形菜单(实例分享)
Dec 21 #Javascript
详解jQuery选择器
Dec 21 #Javascript
如何清除IE10+ input X 文本框的叉叉和密码输入框的眼睛图标
Dec 21 #Javascript
js实现可输入可选择的select下拉框
Dec 21 #Javascript
详解handlebars+require基本使用方法
Dec 21 #Javascript
JS实现的驼峰式和连字符式转换功能分析
Dec 21 #Javascript
JS实现的RGB网页颜色在线取色器完整实例
Dec 21 #Javascript
You might like
把从SQL中取出的数据转化成XMl格式
2006/10/09 PHP
php explode函数实例代码
2012/02/27 PHP
php stripslashes和addslashes的区别
2014/02/03 PHP
php简单防盗链实现方法
2015/07/29 PHP
PHP定义字符串的四种方式详解
2018/02/06 PHP
jquery实现div阴影效果示例代码
2013/09/16 Javascript
在javascript中实现函数数组的方法
2013/12/25 Javascript
将查询条件的input、select清空
2014/01/14 Javascript
javascript原始值和对象引用实例分析
2015/04/25 Javascript
JQuery中层次选择器用法实例详解
2015/05/18 Javascript
JS动态添加iframe的代码
2015/09/14 Javascript
jQuery点击改变class并toggle及toggleClass()方法定义用法
2015/12/11 Javascript
JavaScript中的this机制
2016/01/30 Javascript
原生js的数组除重复简单实例
2016/05/24 Javascript
JavaScript中常用的验证reg
2016/10/13 Javascript
JS简单实现表格排序功能示例
2016/12/20 Javascript
详解Vue 动态添加模板的几种方法
2017/04/25 Javascript
JS匹配日期和时间的正则表达式示例
2017/05/12 Javascript
简述jQuery Easyui一些用法
2017/08/01 jQuery
Angular17之Angular自定义指令详解
2018/01/21 Javascript
JavaScript中EventLoop介绍
2018/01/22 Javascript
vue 简单自动补全的输入框的示例
2018/03/12 Javascript
ng-alain的sf如何自定义部件的流程
2020/06/12 Javascript
[02:45]DOTA2英雄基础教程 伐木机
2013/12/23 DOTA
[50:48]LGD vs CHAOS 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
Python实现的将文件每一列写入列表功能示例【测试可用】
2018/03/19 Python
浅谈Django中的数据库模型类-models.py(一对一的关系)
2018/05/30 Python
keras中的卷积层&amp;池化层的用法
2020/05/22 Python
python如何查看安装了的模块
2020/06/23 Python
基于selenium及python实现下拉选项定位select
2020/07/22 Python
css3 transform属性详解
2014/09/30 HTML / CSS
西铁城美国官方网站:Citizen Watch美国
2019/11/08 全球购物
深圳-东方伟业笔试部分
2015/02/11 面试题
AJAX的全称是什么
2012/11/06 面试题
领导干部民主生活会自我剖析材料范文
2014/09/20 职场文书
MySQL中varchar和char类型的区别
2021/11/17 MySQL