js目录路径转树型结构
pathToTree函数copy自https://www.cnblogs.com/liaozhenting/p/8343827.html
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<head> <title>jquery多级树型标签</title> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="css/tagTree.css" /> <link rel="stylesheet" type="text/css" href="https://www.jq22.com/jquery/font-awesome.4.6.0.css"> <script src="https://www.jq22.com/jquery/jquery-1.10.2.js"></script> <script type="text/javascript" src="js/tagTree.js"></script> <script type="text/javascript"> data = [ "H1.a1.b1.c1.xxxxx", "H1.a1.b1.c2.xxxxx", "H1.a1.b1.c3.xxxxx", "H1.a2.b1.c1.xxxxx1", "H1.a2.b1.c1.xxxxx2", "H1.a2.b1.c1.xxxxx3", "H1.a2.b1.c1.xxxxx4", "H1.a3.b1.c1.xxxxx5", "H1.a3.b1.c1.xxxxx6", "H1.a3.b1.c2.xxxxx", "H1.a3.b1.c3.xxxxx", "H1.a3.b1.c4.xxxxx", "H1.a3.b1.c5.xxxxx", "H1.a3.b1.c6.xxxxx", "H1.a3.b1.c1.xxxxx.xxxx", ]; $(function () { var treedata=pathToTree(data); $("#test").tagTree({ id: "", data: treedata, fold: false, multiple: false, check: function (val) { console.log('chekc:' + val); console.log($(this).tagTreeValues()); }, done: function () { console.log('tagTree is ok!'); } }); }); const pathToTree = (input) => { var output = []; for (var i = 0; i < input.length; i++) { var chain = input[i].split("."); var currentNode = output; for (var j = 0; j < chain.length; j++) { if (chain[j] === '') { break; } var wantedNode = chain[j]; var lastNode = currentNode; for (var k = 0; k < currentNode.length; k++) { if (currentNode[k].name == wantedNode) { currentNode = currentNode[k].children; break; } } if (lastNode == currentNode) { var newNode = currentNode[k] = { value: input[i], name: wantedNode, children: [] }; currentNode = newNode.children; } else { delete currentNode.children } } } return output; } </script> </head> <body> <div id="test"></div> </body> </html>
tree插件:
tagTree.js
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/////////////////////////////////////////////// /// 树型标签 /// V 1.0 /// creat by lee /// https://github.com/miracleren/tagTree /// 20190529 /// 运行库 juqery /// ////////////////////////////////////////// ;(function($){ var defaults ={ id:"", data:[], fold:true, multiple:false, check:function(){}, done:function(){} }; $.fn.tagTree = function(options){ var that = $(this); options.id = "#" + that.attr("id"); var opts = $.extend(defaults, options); that.addClass("tagtree"); setTree(defaults.data,that); $(defaults.id+' li:has(ul)').addClass('li-top'); if(defaults.fold) $(defaults.id+" .li-top li").hide('fast'); $(defaults.id+' li.li-top > span').on('click', function (e) { var children = $(this).parent('li.li-top').find(' > ul > li'); if (children.is(":visible")) { children.hide('fast'); } else { children.show('fast'); } return false; }); $(defaults.id+' li span').hover(function() { if (!$(this).find('i').hasClass('i-check')) $(this).find('i').show(200); }, function() { if (!$(this).find('i').hasClass('i-check')) $(this).find('i').hide(100); }); $(defaults.id+' li span i').click(function(event) { if(!defaults.multiple) { $(defaults.id +" .i-check").removeClass('i-check').hide(100); } if($(this).hasClass('i-check')) $(this).removeClass('i-check'); else $(this).addClass('i-check'); defaults.check($(this).attr("data-val")); return false; }); defaults.done(); } $.fn.tagTreeValues =function(){ var vals = []; $(defaults.id +" .i-check").each(function(index, el) { vals.push($(el).attr('data-val')); }); return vals; } //递归生成树 function setTree(data,that) { var ul = $('<ul></ul>'); that.append(ul); $.each(data,function(index,value){ var li = $('<li><span>'+value.name+'<i data-val="'+value.value+'" class="fa fa-check" style="display:none;"></i></span></li>'); ul.append(li); if(value.children.length > 0) { li.append('<div class="node-count">'+value.children.length+'</div>'); setTree(value.children,li); } }); } })(jQuery);
tagTree.css
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
.tagtree { border: 1px solid #d7d7d7; background-color: #fcfcfc; padding: 10px; } .tagtree ul{ margin-left:-20px; } .tagtree li { margin:0; padding:10px 5px 0 5px; position:relative; list-style-type:none; } .tagtree li::before, .tagtree li::after { content:''; left:-20px; position:absolute; right:auto } .tagtree li::before { border-left:1px dashed #795548; bottom:50px; height:100%; top:-4; width:1px } .tagtree li::after { border-top:1px dashed #795548; height:20px; top:25px; width:25px } .tagtree li span { position: relative; z-index: 1; background-color: #1ABC9C; height: 28px; display: inline-block; padding: 0 8 0 5; font-size: 14px; line-height: 28px; color: white; } .tagtree li span:before { content: ""; position: absolute; z-index: -1; border-top: 14px solid transparent; border-right: 10px solid #1ABC9C; border-bottom: 14px solid transparent; left: -10px; } .tagtree li span { cursor:pointer } .tagtree>ul>li::before, .tagtree>ul>li::after { border:0 } .tagtree li:last-child::before { height:30px } .tagtree li span:hover { background:#16A085; } .tagtree li span:hover::before { border-right: 10px solid #16A085; } .node-count { display: inline-block; font-size: 10px; margin-left: 3px; height: 16px; width: 16px; background-color: #8bc34a; text-align: center; line-height: 16px; color: white; border-radius: 8px; } .tagtree li span i { margin: 0 1 0 6; color: #ECF0F1; font-size: 18px; } .tagtree li span i:hover { color: #FFEB3B; } span .i-check { display: inline-block; color: #FFEB3B !important; }
数据:
data = [
"H1.a1.b1.c1.xxxxx",
"H1.a1.b1.c2.xxxxx",
"H1.a1.b1.c3.xxxxx",
"H1.a2.b1.c1.xxxxx1",
"H1.a2.b1.c1.xxxxx2",
"H1.a2.b1.c1.xxxxx3",
"H1.a2.b1.c1.xxxxx4",
"H1.a3.b1.c1.xxxxx5",
"H1.a3.b1.c1.xxxxx6",
"H1.a3.b1.c2.xxxxx",
"H1.a3.b1.c3.xxxxx",
"H1.a3.b1.c4.xxxxx",
"H1.a3.b1.c5.xxxxx",
"H1.a3.b1.c6.xxxxx",
"H1.a3.b1.c1.xxxxx.xxxx",
]
效果:
最下层节点完整路径保存在<i>标签,data-val属性中