CSS实现树形结构 + js加载数据

  看到一款树形结构,比较喜欢它的样式,就参照它的外观自己做了一个,练习一下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'
}

至于效果,读者自己去试咯。

 

转载于:https://www.cnblogs.com/zengyuanjun/p/8903213.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/452886.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/452886.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python中__init__函数以及参数self

1.class类包含&#xff1a; 类的属性&#xff1a;类中所涉及的变量 类的方法&#xff1a;类中函数 2. _init_函数&#xff08;方法&#xff09; 首先说一下&#xff0c;带有两个下划线开头的函数是声明该属性为私有,不能在类地外部被使用或直接访问。init函数&#xff08;方…

程序的装入方式

1 绝对装入方式 2 可重定位装入方式 3 动态运行时装入方式

嵌套集合模型(Nested set model)介绍

原文链接&#xff1a;www.pilishen.com/posts/an-in… 此文档是 nestedset-无限分类正确姿势的扩展阅读 本文翻译自维基百科Nested set model nested set model(嵌套集合模型)是一种在关系型数据库中表示nested sets&#xff08;嵌套集合&#xff09; 的特殊技术。[nested sets…

互联网商业模式:增值还是减值?

网络可以为服务增值&#xff0c;这是人们的共识。不但是增值&#xff0c;而且是按照用户的平方增值&#xff0c;这是梅特卡夫定律说的。 我认为&#xff0c;网络也可以为服务减值&#xff0c;是按照服务提供商的数量的平方减值。如果按用户增值是网络的第一定律&#xff0c;这…

程序的链接方式

1 静态链接 2 装入时动态链接 3 运行时动态链接

Django中--自定义模型管理器类

BookInfo.objects.all()->objects是一个什么东西呢&#xff1f; 答&#xff1a;objects是models.Manger类的一个对象&#xff0c;是Django帮我自动生成的管理器对象&#xff0c;通过这个管理器可以实现对数据的查询。 自定义管理器之后Django不再帮我们生成默认的objects管…

字符驱动之按键(四:poll机制)

1 采用之前的中断按键法&#xff0c;程序会一直在read函数中死循环。2 使用了poll之后&#xff0c;在一段时间内如果有按键按下就会返回&#xff0c;如果没有按键按下等时间到再返回。3 4 应用程序的open,read,write,poll分别对应了驱动程序的open,read,write和poll。5…

第二章 API的理解和使用

2.1.1全局命令 Key * 查看所有键&#xff0c;(慎用&#xff0c;会把所有键都遍历一次并列出) Dbsize 查看键总数&#xff0c;不会遍历所有键&#xff0c;只是从内置函数中读取一个数 Exists [key] 检查键是否存在 Del [key] 删除键 Expire [key] [seconds] 设置键过期时间 Type…

java uuid 线程安全_java – 在多线程应用程序中生成相同的UUID

我使用UUID.randomUUID().toString()将一个唯一值附加到最终存储在数据库中的字符串,并对其具有唯一约束但是因为我的应用程序是多线程的,所以执行在UUID生成的同时发生,并且最终将相同的UUID附加到字符串并且持久性失败.有没有更好的方法来生成随机字符串,即故障安全方法.我尝…

社会生活、工作中的著名法则

社会生活中的著名法则(1)&#xff1a;马太效应 《新约 马太福音》中有这样一个故事&#xff0c;一个国王远行前&#xff0c;交给三个仆人每人一锭银子&#xff0c;吩咐他们&#xff1a;“你们去做生意&#xff0c;等我回来时&#xff0c;再来见我。”国王回来时&#xff0c;第一…

Django中--使用redis存储历史浏览记录

class UserInfoView(LoginRequiredMixin, View):用户中心-信息页def get(self, request):显示# Django会给request对象添加一个属性request.user# 如果用户未登录->user是AnonymousUser类的一个实例对象# 如果用户登录->user是User类的一个实例对象# request.user.is_aut…

3D虚拟试衣有望解决厘米级服装误差 网购服装不再蒙

还在担心网购服装对实际穿着效果没把握吗&#xff1f;随着京东App 6.6.3版本的更新&#xff0c;京东试试3D虚拟试衣功能正式上线&#xff0c;消费者可按照自己的身材比例创建专属的3D模型&#xff0c;而试穿效果则可以完全依照模型来展现。据了解&#xff0c;这个系统未来还将实…

关于idea修改当前使用的git账户的问题

1、问题描述&#xff1a; 由于前一段时间公司迁移git&#xff0c;就是将项目代码等迁移到另一个git服务器上&#xff0c;结果用idea从git上clone代码的时候发现没有指定仓库,如下提提示 2、排查原因&#xff1a; 开始怀疑是没有把自己加入到项目成员里面&#xff0c;经过检查是…

分页和分段的区别

1.页是信息的物理单位&#xff0c;分页是由于系统管理的需要。段是信息的逻辑单位&#xff0c;分段是为了满足用户的要求。 2.页的大小固定且由系统决定&#xff0c;段的长度不固定&#xff0c;决定于用户所编写的程序&#xff0c;通常由编译程序在对源程序紧进行编译 时&…

java 修饰_Java 修饰符

摘录自http://www.runoob.com/java/java-modifier-types.htmlJava 修饰符Java语言提供了很多修饰符&#xff0c;主要分为以下两类&#xff1a;访问修饰符非访问修饰符修饰符用来定义类、方法或者变量&#xff0c;通常放在语句的最前端。我们通过下面的例子来说明&#xff1a;pu…

内存分配,任意字节对齐

有这么一道题目&#xff0c;要求按任意字节对齐分配内存&#xff0c;接口&#xff1a;char * aligned_malloc(int size, int alignment)//size 为分配的内存大小&#xff0c;alignment对齐基数&#xff08;可以为任意数&#xff09;这个在gcc库函数里能找到源码&#xff0c;在f…

day16-Dom提交表单以及其他

一、前言 之前我们学习的是from提交表单&#xff0c;那个是html的提交表单方式&#xff0c;现在我们用dom来提交表单&#xff0c;还有一些其他的方式 二、dom提交表单 2.1、html提交表单 说明&#xff1a;form标签跟submit类型的input标签结合 <body><form id"f1…

分布式文件系统FastDFS

1. 什么是FastDFS FastDFS 是用 c 语言编写的一款开源的分布式文件系统。FastDFS 为互联网量身定制&#xff0c; 充分考虑了冗余备份、负载均衡、线性扩容等机制&#xff0c;并注重高可用、高性能等指标&#xff0c;使用 FastDFS 很容易搭建一套高性能的文件服务器集群提供文件…

html5 下拉刷新(pc+移动网页源码)

本文demo下载地址&#xff1a;http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId1071 本文实现在html5网页中使用下拉功能自动刷新显示更多内容, 使用jquery捕捉和处理相应的鼠标事件, 例如内容在顶部时&#xff0c;触发下拉事件后显示更多内容; 如内容在…

操作系统内存管理问题集锦

1. 可采用哪几种方式将程序装入内存?它们分别适用于何种场合? a. 首先由编译程序将用户源代码编译成若干目标模块&#xff0c;再由链接程序将编译后形成的目标模块和所需的-库函数链接在一起&#xff0c;组成一个装入模块&#xff0c;再由装入程序将装入模块装入内存&#x…