看到一款树形结构,比较喜欢它的样式,就参照它的外观自己做了一个,练习一下CSS。
做出来的效果如下:
- 拉莫小学
- 一年级
- 一班
- 二班
- 二年级
- 三年级
- 一班
- 二班
- 三班
- 一年级
树的dom结构:
<div class="tree"> ???<ul> ???????<li> ???????????<span><i class="fa fa-minus-circle"></i>拉莫小学</span> ???????????<ul> ???????????????<li> ???????????????????<span><i class="fa fa-minus-circle"></i>一年级</span> ???????????????????<ul> ???????????????????????<li><span>一班</span></li><li><span>二班</span></li> ???????????????????</ul> ???????????????</li> ???????????????<li> ???????????????????<span>二年级</span> ???????????????</li> ???????????????<li> ???????????????????<span><i class="fa fa-minus-circle"></i>三年级</span> ???????????????????<ul> ???????????????????????<li><span>一班</span></li> ???????????????????????<li><span>二班</span></li> ???????????????????????<li><span>三班</span></li> ???????????????????</ul> ???????????????</li> ???????????</ul> ???????</li> ???</ul></div>
CSS代码:
/** tree.css zyj 2018.4.21 */ul,li{list-style-type:none;}.tree{display:block;position:relative;padding:5px 15px;}.tree span{display:inline-block;box-sizing:border-box;height:30px;line-height:28px;min-width:60px;text-align:center;color:#888;border:1px solid #ddd;border-radius:5px;padding:0 8px;}.tree ul{position:relative;padding-left:60px;margin:0;}.tree ul>li{position:relative;padding:5px 0;}.tree>ul{padding:0;margin:0;}/** 水平方向连线 */.tree>ul ul>li:after{content:‘ ‘;position:absolute;top:20px;left:-45px;width:45px;border:none;border-top:1px solid #ddd;}/** 垂直方向连线 */.tree ul>li:not(:last-child):before{content:‘ ‘;position:absolute;top:0;left:-45px;height:100%;border:none;border-left:1px solid #ddd;}.tree ul>li:last-child:before{content:‘ ‘;position:absolute;top:0;left:-45px;height:20px;border:none;border-left:1px solid #ddd;}/** 控制鼠标移上去的颜色 */.tree span:hover, .tree span:hover+ul span{color:#fff;background-color:orange;}.tree span:hover, .tree span:hover+ul span, .tree span:hover+ul li:before, .tree span:hover+ul li:after{border-color:orange;}/** 折叠图标 */.tree .fa:before{margin-right:5px;}.tree .fa-minus-circle, .tree .fa-plus-circle{cursor:pointer;}
里面引的fontawesome图标没法加载进来,导致折叠按钮显示不出,下面是原始树状图的截图:
数据是我用JS加载的,写了个加载数据的tree.js文件,源码如下:
/** tree.js zyj 2018.4.22 */(function(name){ ???var tree, outer, defaultDateFormat; ???????outer = { ???????setData : setData, ???}; ???????defaultDateFormat = { ???????????unfold : true, ???????????name : ‘name‘, ???????????childName : ‘children‘ ???}; ???function getDataFormat(dataFormat){ ???????var index; ???????if(!dataFormat){ ???????????return defaultDateFormat; ???????} ???????for(index in defaultDateFormat){ ???????????dataFormat[index] = typeof dataFormat[index] == ‘undefined‘? defaultDateFormat[index] : dataFormat[index]; ???????} ???????return dataFormat ???} ???????function initTreeJs(name){ ???????var tree; ???????if(checkTreeNameUsed(name)){return;} ???????window[name] = outer; ???????initFoldIcon($(‘.tree‘)); ???} ???????function checkTreeNameUsed(name){ ???????if(window[name]){ ???????????console.error("The window object name [" + name + "] has been used, tree.js can‘t be loaded! You can try another name." ); ???????????return true; ???????} ???????return false; ???} ???????function initFoldIcon(target){ ???????target.off(‘click‘, ‘span>i.fa‘).on(‘click‘, ‘span>i.fa‘, function(e){ ???????????var ele = $(e.target); ???????????if(ele.hasClass(‘fa-minus-circle‘)){ ???????????????ele.removeClass(‘fa-minus-circle‘).addClass(‘fa-plus-circle‘).parent().next(‘ul‘).hide(200); ???????????}else if(ele.hasClass(‘fa-plus-circle‘)){ ???????????????ele.removeClass(‘fa-plus-circle‘).addClass(‘fa-minus-circle‘).parent().next(‘ul‘).show(200); ???????????} ???????}) ???} ???????function getJqueryObjectBySelector(selector){ ???????var ele = $(selector); ???????if(typeof selector != ‘string‘){ ???????????console.error("The first parameter jquery selector [" + selector + ?"] must be a string!" ); ???????????return; ???????} ???????if(!ele.hasClass(‘tree‘)){ ???????????ele = ele.find(‘.tree‘); ???????} ???????if(ele.length != 1){ ???????????console.error("The selector [" + selector + ?"] expect only one element!" ); ???????????return; ???????} ???????return ele; ???} ???????function setData(selector, data, dataFormat){ ???????var ele = getJqueryObjectBySelector(selector); ???????if(!ele){return;} ???????if(!data){return;} ???????if(!data.length){ ???????????data = [data]; ???????} ???????dataFormat = getDataFormat(dataFormat); ???????dataFormat.topElement = true; ???????ele.empty().append(getTreeList(data, dataFormat)); ???????initFoldIcon(ele); ???} ???????function getTreeList(data, dataFormat){ ???????var i, single, name, children, childDataFormat, ????????????array = []; ???????childDataFormat = dataFormat.child || dataFormat; ???????if(dataFormat.unfold){ ???????????array.push(‘<ul>‘); ???????}else if(dataFormat.topElement){ ???????????dataFormat.topElement = false; ???????????array.push(‘<ul>‘); ???????}else{ ???????????array.push(‘<ul style="display:none;">‘); ???????} ???????for(i=0; i<data.length; i++){ ???????????single = data[i]; ???????????if(typeof dataFormat.name == ‘function‘){ ???????????????name = dataFormat.name(single); ???????????}else if(typeof dataFormat.name == ‘string‘){ ???????????????name = single[dataFormat.name]; ???????????}else{ ???????????????name = single[‘name‘]; ???????????} ???????????if(typeof dataFormat.childName == ‘string‘){ ???????????????children = single[dataFormat.childName]; ???????????}else{ ???????????????children = single[‘children‘]; ???????????} ???????????array.push(‘<li>‘); ???????????array.push(‘<span>‘); ???????????if(children && children.length > 0){ ???????????????if(dataFormat.unfold){ ???????????????????array.push(‘<i class="fa fa-minus-circle"></i>‘); ???????????????}else{ ???????????????????array.push(‘<i class="fa fa-plus-circle"></i>‘); ???????????????} ???????????????array.push(name); ???????????????array.push(‘</span>‘); ???????????????array.push(getTreeList(children, childDataFormat)); ???????????}else{ ???????????????array.push(name); ???????????????array.push(‘</span>‘); ???????????} ???????????array.push(‘</li>‘); ???????} ???????array.push(‘</ul>‘); ???????return array.join(‘‘); ???} ???????initTreeJs(name);}(‘tree‘))
偷懒没写注释,tree.js中目前只写了一个对外的接口 tree.setData(selector, data, dataFormat) 。参数selector是jQuery选择器,data是数据,dataFormat是数据格式。
比如加载上图的数据:
var dataTest = {name:‘拉莫小学‘, children:[ ??{ ??????name:‘一年级‘, ??????children:[ ??????????{name:‘一班‘}, ??????????{name:‘二班‘} ??????] ??}, ??{ ??????name:‘二年级‘ ??}, ??{ ??????name:‘三年级‘, ??????children:[ ??????????{name:‘一班‘}, ??????????{name:‘二班‘}, ??????????{name:‘三班‘} ??????] ??}]};tree.setData(‘.tree‘, dataTest);
由于后台加载的数据不一定是按照{name:‘*‘, children:[{name:‘*‘},...]}这种结构,所以留了dataFormat参数,自己去定义数据格式。
简单举个例子,假如后台数据格式是
var data =
{ ???id : ‘1‘, ???title : ‘百度‘, ???url : ‘http://www.baidu.com‘, ???subWeb : ????[ ????????{ ????????????id : ‘2‘, ????????????title : ‘百度新闻‘, ????????????url : ‘http://news.baidu.com‘ ????????}, ????????{ ????????????id : ‘3‘, ????????????title : ‘百度知道‘, ????????????url : ‘http://zhidao.baidu.com‘ ????????}, ????????{ ????????????id : ‘4‘, ????????????title : ‘百度图片‘, ????????????url : ‘http://image.baidu.com‘ ????????}, ????]}
那么dataFormat可以定义为
var dataFormat = { ???name : function(data){ ???????return ‘<a href="‘ + data.url + ‘">‘ + data.title + ‘</a>‘; ???}, ???childName : ‘subWeb‘}
至于效果,读者自己去试咯。
CSS实现树形结构 + js加载数据
原文地址:https://www.cnblogs.com/zengyuanjun/p/8903213.html