Web 前端实战(二):JQuery 实现树形控件
2022-05-23 14:27
3059 查看
前言
这是一篇个人练习 Web 前端各种常见的控件、组件的实战系列文章。本篇文章将介绍个人通过 JQuery + 无序列表 + CSS 动画完成一个简易的树形控件。
最终实现的效果是:
这样结构比较复杂的嵌套再嵌套的 HTML 结构必须先写一个静态的观察,不可能一步到位,事情是逐渐发展的。遵循自顶向下、逐步求精、模块化三个原则。
静态实现
HTML
点击查看 HTML 代码<ul class="category"> <li class="category-item" data-displayed="false"> <div class="category-tip">分类</div> <ul class="sub-category"> <li class="sub-category-item">item 01</li> <li class="sub-category-item">item 02</li> <li class="sub-category-item">item 03</li> </ul> </li> <li class="category-item" data-displayed="false"> <div class="category-tip">分类</div> <ul class="sub-category"> <li class="sub-category-item">item 01</li> <li class="sub-category-item">item 02</li> </ul> </li> <li class="category-item" data-displayed="false"> <div class="category-tip">分类</div> <ul class="sub-category"> <li class="sub-category-item">item 01</li> </ul> </li> </ul>
基本的结构设计就是,在外层是无序列表 ul,每一项内容 li 下面嵌套 div 和 ul 标签。每一层数据展示是类名为
category-tip的标签,如果标签下面还有可以展开的内容就有
sub-cagetory的 ul。
CSS
点击查看 CSS 代码.category-item { cursor: pointer; --li-height: 0; } .category-item-active { animation: category-display 0.18s cubic-bezier(0.42, 0, 0.18, 0.98) 0s; } .sub-category { display: none; } .sub-category-active { display: block; animation: category-show 0.6s ease-in-out 0s; } @keyframes category-show { from { opacity: 0; } to { opacity: 1; } } @keyframes category-display { from { height: 0; } to { height: var(--li-height); } }
观察最开始的效果展示可知,
category-item被点击时需要展开到其子节点
sub-category的高度。子节点需要有一种渐变的效果,动画设置的时间要比
category-item节点展开的时间长一点。
JQuery
$(".category-item").on("click", function () { let displayed = $(this)[0].dataset.displayed; if ( displayed === "false" ) { $(this).css({ "--li-height": `${ $(this).children(".sub-category").height() }px` }); $(this).addClass("category-item-active"); $(this).children(".sub-category").addClass("sub-category-active"); $(this)[0].dataset.displayed = "true"; } else { $(this).removeClass("category-item-active"); $(this).children(".sub-category").removeClass("sub-category-active"); $(this)[0].dataset.displayed = "false"; } });
要实现列表展开和收缩,必须要知道当前节点是否已经展开?因此,就必须给节点标记一个布尔值以便于判断是否展开的状态,正好 HTML 标签支持
data-xxx的属性,我们可以把这个布尔值直接放在每一个需要展开的标签中:
<li class="category-item" data-displayed="false">......</li>
当点击节点时,JQuery 需要判断
data-displayed是否已经展开,如果展开就移除
category-item-active以及
sub-category-active的动画;如果没有展开就添加这两个动画,实现展开效果。
改进
category-item-active有一个重大问题,就是点击时节点有类似于重影的重合效果。经过多次调试发现,动画开始时,高度从 0px 开始,所以发生了重影效果。正确是高度从
category-tip的高度开始,到
category-tip和
sub-category结束。
$(this).css({ "--tip-height": `${ $(this).children(".category-tip").height() }px`, "--li-height": `${ $(this).children(".sub-category").height() }px`, });
@keyframes category-display { from { height: 0; } to { height: calc(var(--li-height) + var(--tip-height)); } }
动态实现
上面都还是静态实现,树形控件肯定是多层的,接下来我们将写一个渲染树形控件的函数,并且用到递归函数完成 HTML 的渲染。
通过上面静态案例可知,抽离其数据为 JS 数组:
let treeOcxData = [ { tip: "分类", child: [ { tip: "设计作品" }, { tip: "技巧杂烩", child: [ { tip: "Web 前端" } ] } ] }, { tip: "导航", child: [ { tip: "固钉" }, { tip: "回到顶部" }, { tip: "面包屑" } ] }, { tip: "数据展示" } ];
抽离出来之后数据还是挺复杂的,不要慌,万事开头难。首先写一个递归函数能不能实现遍历所有的数据。
递归遍历数据
function rendTreeOcx(data) { for ( let i = 0; i < data.length; i++ ) { console.log(data[i].tip); if ( data[i].child ) { rendTreeOcx(data[i].child); } } }
每一个数据都成功的遍历出来了,接下来就是渲染 HTML。
渲染树形控件函数
点击查看 JS 代码function rendTreeOcx(data, enableFold) { let template = `<ul class="tree-ocx-ul">`; if ( enableFold ) template = `<ul class="tree-ocx-ul tree-ocx-ul-enable-fold">`; for ( let i = 0; i < data.length; i++ ) { if ( data[i].child ) { template += ` <li class="tree-ocx-li tree-ocx-li-enable-fold" data-is-folded="false"> <div class="tree-ocx-tip"> ${ data[i].tip } </div> ${ rendTreeOcx(data[i].child, true) } `; } else { template += ` <li class="tree-ocx-li"> <div class="tree-ocx-tip tree-ocx-tip-normal">${ data[i].tip }</div> `; } template += `</li>`; } template += `</ul>`; return template; }
如果还有子节点就在
if ( data[i].child )体内执行递归函数,否则就完成这一层的 HTML。
后面的样式基本上没有什么变化,完整代码请看:Gitee 仓库-当前案例-完整代码-v2.0
相关文章推荐
- Web前端开发实战3:二级下拉式菜单之jQuery实现
- 使用反映实现前端WEB窗口控件与后台数据库类对象的动态绑定
- 使用 jQuery.i18n.properties 实现 Web 前端的国际化
- 利用jQuery.i18n实现web前端的国际化
- web前端复习(一):jquery实现轮播
- 美观实用值得收藏的Web前端日期控件的实现(下)
- web前端,jquery实现瀑布流总结4,数组
- 基于jQuery实现多标签页切换的效果(web前端开发)
- 使用 jQuery.i18n.properties 实现Web 前端的国际化
- web前端,html+css+jquery实现竖直菜单
- web前端,jquery实现列表点击条目改变样式并拿到属性值总结1index()
- 使用 jQuery.i18n.properties 实现 Web 前端的国际化
- 基于jQuery实现多标签页切换的效果(web前端开发)
- 使用jquery.i18n.properties 实现web前端国际化
- 最新《 Web前端开发Jquery高级进阶及移动端开发项目实战》
- NHibernate+spring.net+jquery打造UI控件库(mvc+webform两种实现) accordion控件的初步实现(附代码下载)
- 使用 jQuery.i18n.properties 实现 Web 前端的国际化
- web的各种前端打印方法之jquery打印插件PrintArea实现网页打印
- web前端,html+css+jquery实现水平菜单
- web前端,jquery实现列表点击条目改变样式并拿到属性值