js实现后管无限级菜单递归一
2017-12-29 16:25
507 查看
递归后管菜单
递归就是函数自调用之前做后管,刚开始后管菜单就三级,所有嵌套三层循环就可以.但是有些插件方需要四级或五级菜单.如果不用递归,一直嵌套循环也是可以的.只是写着写着觉得这样循环写代码太长了很难看.每次改动也很麻烦.再想能不能用递归做成自动化呢.
直接代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"> <style> * {margin: 0; padding: 0;} ul {list-style: none;} header {height: 60px;padding: 0 20px;line-height: 60px;background: #3c8dbc;} .logo{float: left;} .userinfo {float: right} aside {position: fixed;left:0;top:0;width: 230px;height: 100%;margin-top: 60px;padding: 20px;background: #2d2d2d;color: #fff;} .panel {margin-bottom: 0;} aside>ul>li.panel {margin-bottom: 15px;} </style> </head> <body> <div class="wrap"> <header> <div class="logo">logo</div> <div class="userinfo">用户信息</div> </header> <aside id="aside"></aside> <div class="content"> <iframe src="" frameborder="0"></iframe> </div> </div> <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> <script type="text/javascript" src="http://apps.bdimg.com/libs/bootstrap/3.3.4/js/bootstrap.min.js"></script> <script type="text/javascript"> //ajax后台请求得到的数据 var data = {"data": {"list": [ {"id": "no1", "name": "菜单管理", "url": "no1.do", "list": [ {"id": "no11", "name": "二级菜单-1", "url": "no11.do", "list": [ {"id": "no111", "name": "三级菜单-1", "url": "no111.do", "list": [ {"id": "no1111", "name": "四级菜单-1", "url": "no1111.do", "list": []}, {"id": "no1112", "name": "四级菜单-2", "url": "no1112.do", "list": []} ]}, {"id": "no112", "name": "三级菜单-2", "url": "no112.do", "list": [ {"id": "no1121", "name": "四级菜单-1", "url": "no1121.do", "list": []}, {"id": "no1122", "name": "四级菜单-2", "url": "no1122.do", "list": []} ]} ]}, {"id": "no12", "name": "二级菜单-2", "url": "no12.do", "list": [ {"id": "no121", "name": "三级菜单-1", "url": "no121.do", "list": [ {"id": "no1211", "name": "四级菜单-1", "url": "no1211.do", "list": []}, {"id": "no1212", "name": "四级菜单-2", "url": "no1212.do", "list": []} ]}, {"id": "no122", "name": "三级菜单-2", "url": "no122.do", "list": [ {"id": "no1221", "name": "四级菜单-1", "url": "no1221.do", "list": []}, {"id": "no1222", "name": "四级菜单-2", "url": "no1222.do", "list": []} ]} ]} ]}, {"id": "no2", "name": "一级菜单-2", "url": "no2.do", "list": [ {"id": "no21", "name": "二级菜单-1", "url": "no21.do", "list": [ {"id": "no211", "name": "三级菜单-1", "url": "no111.do", "list": [ {"id": "no2111", "name": "四级菜单-1", "url": "no1111.do", "list": []}, {"id": "no2112", "name": "四级菜单-2", "url": "no1112.do", "list": []} ]}, {"id": "no212", "name": "三级菜单-2", "url": "no212.do", "list": [ {"id": "no2121", "name": "四级菜单-1", "url": "no1121.do", "list": []}, {"id": "no2122", "name": "四级菜单-2", "url": "no1122.do", "list": []} ]} ]}, {"id": "no22", "name": "二级菜单-2", "url": "no22.do", "list": [ {"id": "no221", "name": "三级菜单-1", "url": "no221.do", "list": [ {"id": "no2211", "name": "四级菜单-1", "url": "no2211.do", "list": []}, {"id": "no2212", "name": "四级菜单-2", "url": "no2212.do", "list": []} ]}, {"id": "no222", "name": "三级菜单-2", "url": "no222.do", "list": [ {"id": "no2221", "name": "四级菜单-1", "url": "no2221.do", "list": []}, {"id": "no2222", "name": "四级菜单-2", "url": "no2222.do", "list": []} ]} ]} ]} ]}} var res = data.data.list, html; function asideTpl() { var tpl = '<ul id="accordion" class="nav nav-sidbar">'; res.forEach(function(val) { tpl += '<li class="panel"><a data-parent="#accordion" href="javascript:;" data-toggle="collapse" data-url="'+val.url+'" data-target="#parent-'+val.id+'" id="parent-a-'+val.id+'" class="parent jumpiframe">' + val.name + '</a><ul class="nav collapse" id="parent-'+val.id+'">'+createli(val.id, val.list, "")+'</ul></li>'; }); return tpl + '</ul'; } function createli(pid, data, str) { data && data.forEach(function(val) { str += '<li class="panel"><a style="text-indent: 10px" href="javascript:;" data-toggle="collapse" data-parent="#parent-'+pid+'" data-url="'+val.url+'" data-target="#parent-'+val.id+'" id="parent-a-'+val.id+'" class="children jumpiframe">' + val.name + '</a><ul class="nav collapse" id="parent-'+val.id+'">'+createli(val.id, val.list, "")+'</ul></li>'; }); return str; } html = asideTpl(); document.querySelector('#aside').innerHTML = html; $(".jumpiframe").on('click', function() { var indent = $(this).css('text-indent'), jumpClass = $(this).attr('class'); if (/children/.test(jumpClass)) { $(this).next().children('li').children('a').css('text-indent', indent.match(/\d+/g)[0] - 0 + 10 + 'px'); } }) </script> </body> </html>
代码分析
data是后台返回的对象数据(里面有很多嵌套)很难看,我这里写的还是简易版.真实的数据更多更复杂.如果大家看的晕,可以复制到浏览器查看这个模板是用bootstrap-collapse来实现左侧菜单功能.样式是丑,但不是重点.重点是递归用法
如果不考虑”递归层次前缀显示”(找不到其它词了). 那么直接将data渲染为html.并不难.此处不做讲解
难点是”递归层次前缀显示”(这里用text-indent来表示).
举例:
{"id": "no1111", "name": "四级菜单-1", "url": "no1111.do", "list": []},这层对象在data对象里属于第三层嵌套,那么text-indent值就是30px.但是这个”3”怎么拿到了,这是难点.
我也测试很久,发现很难就放弃这种方法.改为通过事件来设置
$(this).next().children('li').children('a'))的text-indent.这样点击时先获取点击父a标签的text-index.再设置所点击子菜单a标签的text-indent来间接实现”递归层次前缀显示”
后台返回一维数组递归(不是层级嵌套数据结构)
下次再介绍,相关文章推荐
- js实现后管无限级菜单递归二
- Vue.js 递归组件实现树形菜单
- DataTable 递归 简单的程序,来实现无限级列表 结合 jquery.table.js 实现
- 在jsp中使用jstl,不使用JS,实现递归,生成N级菜单
- 后台树状菜单,js实现递归无限分类
- vue.js 树菜单 递归组件树来实现
- Vue.js 递归组件实现树形菜单(实例分享)
- CSS+JS实现结构化无限级导航菜单列表(直接调用)
- js实现左侧无限级菜单
- js实现递归菜单无限层
- 用 Vue.js 递归组件实现可折叠的树形菜单(demo)
- [置顶] 递归 加引用 实现tree 和 无限级菜单
- 用js枚举实现简易菜单效果
- js+xml实现二级菜单
- js实现多选项切换导航菜单的方法
- JS+Div实现的阴影菜单
- js实现简单的联动菜单效果
- JS实现子父节点菜单的添加
- 利用多叉树实现Ext JS中的无限级树形菜单(一种构建多级有序树形结构JSON的方法)
- PHP无限级分类实现(递归+非递归)