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 相关文章推荐
javascript String 的扩展方法集合
Jun 01 Javascript
Angularjs实现分页和分页算法的示例代码
Dec 23 Javascript
Angular.js去除页面中显示的空行方法示例
Mar 30 Javascript
详解webpack异步加载业务模块
Jun 23 Javascript
纯js实现的积木(div层)拖动功能示例
Jul 19 Javascript
使用webpack搭建react开发环境的方法
May 15 Javascript
jQuery实现为动态添加的元素绑定事件实例分析
Sep 07 jQuery
微信小程序自定义toast的实现代码
Nov 16 Javascript
express express-session的使用小结
Dec 12 Javascript
使用Layui搭建后台管理界面的操作方法
Sep 20 Javascript
vue-element-admin 菜单标签失效的解决方式
Nov 12 Javascript
JS插入排序简单理解与实现方法分析
Nov 25 Javascript
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
编译问题
2006/10/09 PHP
PHP生成便于打印的网页
2006/10/09 PHP
Zend Framework教程之Bootstrap类用法概述
2016/03/14 PHP
PHP QRCODE生成彩色二维码的方法
2016/05/19 PHP
PHP与Perl之间知识点区别整理
2019/03/19 PHP
javascript 选择文件夹对话框(web)
2009/07/07 Javascript
一步一步教你写一个jQuery的插件教程(Plugin)
2009/09/03 Javascript
js解析与序列化json数据(三)json的解析探讨
2013/02/01 Javascript
js获取php变量的实现代码
2013/08/10 Javascript
Javascript验证上传图片大小[前台处理]
2014/07/18 Javascript
兼容主流浏览器的JS复制内容到剪贴板
2014/12/12 Javascript
javascript使用prototype完成单继承
2014/12/24 Javascript
举例详解JavaScript中Promise的使用
2015/06/24 Javascript
AngularJS使用ngOption实现下拉列表的实例代码
2016/01/23 Javascript
微信小程序 rpx 尺寸单位详细介绍
2016/10/13 Javascript
快速实现JS图片懒加载(可视区域加载)示例代码
2017/01/04 Javascript
JS/jQuery实现简单的开关灯效果【案例】
2019/02/19 jQuery
Vue项目使用localStorage+Vuex保存用户登录信息
2019/05/27 Javascript
JS造成内存泄漏的几种情况实例分析
2020/03/02 Javascript
跟老齐学Python之变量和参数
2014/10/10 Python
python解析基于xml格式的日志文件
2017/02/25 Python
对python3标准库httpclient的使用详解
2018/12/18 Python
python-opencv 将连续图片写成视频格式的方法
2019/01/08 Python
pyqt5移动鼠标显示坐标的方法
2019/06/21 Python
Python使用scipy模块实现一维卷积运算示例
2019/09/05 Python
python获取依赖包和安装依赖包教程
2020/02/13 Python
用python对excel查重
2020/12/07 Python
HTML5 Canvas实现平移/放缩/旋转deom示例(附截图)
2013/07/04 HTML / CSS
个人简历中的自我评价范例
2013/10/29 职场文书
优秀团员事迹材料2000字
2014/08/20 职场文书
消防志愿者活动方案
2014/08/23 职场文书
欢迎家长标语
2014/10/08 职场文书
房屋所有权证明
2014/10/20 职场文书
写给女朋友的检讨书
2015/05/06 职场文书
3050和2060哪个好 性能差多少 差距有多大 谁更有性价比
2022/06/17 数码科技
CSS的calc函数用法小结
2022/06/25 HTML / CSS