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.mzph.cn/news/452886.shtml

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

相关文章

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

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

第二章 API的理解和使用

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

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;经过检查是…

分布式文件系统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;触发下拉事件后显示更多内容; 如内容在…

java同名变量在list中添加两次_快速解决List集合add元素,添加多个对象出现重复的问题...

首先我们在new 一个对象的时候&#xff0c;对象的id是唯一确定的&#xff1b;将对象add入list中时&#xff0c;放入list中的其实是对象的引用 &#xff1b;而每次循环只是简单的set 对象的属性&#xff0c;set新的属性值&#xff0c;而add进list中的对象还是同一个对象id&#…

python面试题总结(1)--语言特性

1. 谈谈对 Python 和其他语言的区别 答&#xff1a; Python 是一门强类型的可移植、可扩展、可嵌入的解释型编程语言&#xff0c;属于动态语言&#xff1b;其语法简洁优美、功能强大无比、应用领域非常广泛且具有强大完备的第三方库。 &#xff08;注&#xff1a;语言有无类型…

视频网站盈利模式与营销策划

在与数十家视频网站进行信息网络传播权交易过程中&#xff0c;在研究视频网站内容和盈利模式基础上&#xff0c;综合自己在传统媒体和新媒体领域十几年的策划和营销经验&#xff0c;我发现&#xff1a;视频网站的盈利模式其实早就形成多种体系&#xff0c;但是盈利之路艰难&…

[UWP]了解模板化控件(4):TemplatePart

原文:[UWP]了解模板化控件(4)&#xff1a;TemplatePart1. TemplatePart TemplatePart&#xff08;部件&#xff09;是指ControlTemplate中的命名元素。控件逻辑预期这些部分存在于ControlTemplate中&#xff0c;并且使用protected DependencyObject GetTemplateChild(String ch…

动态重定位的增加的紧凑功能

动态重定位增加了紧凑的功能&#xff0c;在动态的分区分配时&#xff0c;可以对外部碎片进行紧凑来为没有内存空间进行存储的进程进行分配。

java 重载 equals_实现Student类的equals重载函数

[java]代码库//测试类public class StudentDemo {public static void main(String[] args) {Student s1 new Student("000","张三",18);Student s2 new Student("000","张三",18);//随便改boolean flag s1.equals(s2);System.out.p…

python面试题总结(3)-- 数据类型(字符串)

1. 列举 Python 中的基本数据类型&#xff1f; 答&#xff1a; Python3 中有六个标准的数据类型&#xff1a;数字&#xff08;Number&#xff09;、字符串&#xff08;String&#xff09;、列表&#xff08;List&#xff09;、元组&#xff08;Tuple&#xff09;、集合&#…

Jetty - Container源码分析

1. 描述 Container提供管理bean的能力。 基于Jetty-9.4.8.v20171121。 1.1 API public interface Container {// 增加一个bean&#xff0c;如果bean是一个Container.Listener则隐含调用addEventListener(Container.Listener)方法// Container.Listener只关心两个事件&#xff1…

Ubuntu中安装FastDFS

1 安装fastdfs依赖包 解压缩libfastcommon-master.zip进入到libfastcommon-master的目录中执行 ./make.sh执行 sudo ./make.sh install 2 安装fastdfs 解压缩fastdfs-master.zip进入到 fastdfs-master目录中执行 ./make.sh执行 sudo ./make.sh install 3 配置跟踪服务器tra…

python基本语句及其意思_Python语法基础(1),一

一、Python的对象模型对象是Python语言中最基本的概率&#xff0c;在Python中处理的一切都是对象。Python中许多内置对象可提供编程者使用&#xff0c;内置对象可直接使用&#xff0c;如数字、字符串、列表 、del等&#xff1b;非内置对象需要导入模块才能使用&#xff0c;如正…

Ubuntu中安装nginxError

问题1&#xff1a;出现如下错误&#xff1a; ./configure: error: the HTTP rewrite module requires the PCRE library. You can either disable the module by using --without-http_rewrite_module option, or install the PCRE library into the system, or build the PCR…

esrgan_ESRGAN: Enhanced Super-Resolution Generative Adversarial Networks【阅读笔记】

针对SRGAN提出的几点改进&#xff0c;获得了PIRM2018视觉质量的第一名。首先是使用去掉BN层的Residual in Residual Dense Block作为网络的basic unit。并且使用residual scling 和 smaller initialization帮助训练更深的网络。第二点改进是使用了Relativistic Discriminator来…