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

发布时间 - 2026-01-10 22:00:19    点击率:

简要介绍:  

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

bootstrap-treeview:

组件介绍:https://www./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.由于个人技术水平有限,难免出现错误,请多多指正 :)

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


# Bootstrap  # treeview  # bootstrap树控件  # Bootstrap树形菜单  # TreeView.js树形菜单  # Android TreeView实现带复选框树形组织结构  # 对Python 窗体(tkinter)树状数据(Treeview)详解  # bootstrap treeview 树形菜单带复选框及级联选择功能  # WPF自定义TreeView控件样式实现QQ联系人列表效果  # Bootstrap treeview实现动态加载数据并添加快捷搜索功能  # Android UI 之实现多级树形列表TreeView示例  # Bootstrap树形菜单插件TreeView.js使用方法详解  # 浅析BootStrap Treeview的简单使用  # GTK treeview原理及使用方法解析  # 树状  # 写了  # 的是  # 都是  # 我就  # 这一  # 第一个  # 则是  # 可以通过  # 去看  # 得很  # 第二个  # 去做  # 并将  # 有兴趣  # 自定义  # 为其  # 如图  # 所示  # 跳转 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何用PHP快速搭建高效网站?分步指南  如何在云主机上快速搭建网站?  哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?  西安专业网站制作公司有哪些,陕西省建行官方网站?  PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)  Laravel如何使用模型观察者?(Observer代码示例)  Win11关机界面怎么改_Win11自定义关机画面设置【工具】  油猴 教程,油猴搜脚本为什么会网页无法显示?  Laravel PHP版本要求一览_Laravel各版本环境要求对照  Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能  jQuery 常见小例汇总  Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载  Laravel广播系统如何实现实时通信_Laravel Reverb与WebSockets实战教程  高端网站建设与定制开发一站式解决方案 中企动力  如何在万网开始建站?分步指南解析  Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验  如何生成腾讯云建站专用兑换码?  laravel怎么配置Redis作为缓存驱动_laravel Redis缓存配置教程  企业网站制作这些问题要关注  如何用低价快速搭建高质量网站?  什么是javascript作用域_全局和局部作用域有什么区别?  如何在腾讯云服务器快速搭建个人网站?  *服务器网站为何频现安全漏洞?  详解CentOS6.5 安装 MySQL5.1.71的方法  Midjourney怎样加参数调细节_Midjourney参数调整技巧【指南】  利用vue写todolist单页应用  Laravel如何使用集合(Collections)进行数据处理_Laravel Collection常用方法与技巧  如何快速搭建高效服务器建站系统?  Android中AutoCompleteTextView自动提示  php json中文编码为null的解决办法  Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解  动图在线制作网站有哪些,滑动动图图集怎么做?  EditPlus中的正则表达式 实战(4)  Win11搜索栏无法输入_解决Win11开始菜单搜索没反应问题【技巧】  Swift中循环语句中的转移语句 break 和 continue  使用Dockerfile构建java web环境  php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】  如何快速选择适合个人网站的云服务器配置?  js实现获取鼠标当前的位置  Google浏览器为什么这么卡 Google浏览器提速优化设置步骤【方法】  深入理解Android中的xmlns:tools属性  Laravel怎么生成URL_Laravel路由命名与URL生成函数详解  HTML5打空格有哪些误区_新手常犯的空格使用错误【技巧】  高端建站如何打造兼具美学与转化的品牌官网?  长沙企业网站制作哪家好,长沙水业集团官方网站?  Laravel任务队列怎么用_Laravel Queues异步处理任务提升应用性能  实现点击下箭头变上箭头来回切换的两种方法【推荐】  儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?  Laravel Eloquent:优雅地将关联模型字段扁平化到主模型中  LinuxShell函数封装方法_脚本复用设计思路【教程】