说明
- 先根据数据渲染,然后再实现事件
渲染
- 在项目中,经常会给出一个深度不确定的数组,数字结构如下:
data = [
{name: 'a', child:[{name: 'a1'},{name: 'a2', child: [{name:'a21'}]}]},
{name: 'b'}
]
- 要求将数组渲染成对应的目录结构, 结构如下:
<ul>
<li>
a
<ul>
<li>a1</li>
<li>a2
<ul>
<li>a21</li>
</ul>
</li>
</ul>
</li>
<li>b</li>
</ul>
- 思路,先对数组中的第一级数据显示出来
$(function(){
var str = '<ul>';
for(var i=0; i< data.length; i++){
str += `<li>${data[i].name}</li>`
}
str += '</ul>';
$('.tree').html(str)
})
此时页面结构如下:
- 下面尝试将页面结构渲染成如下
<div class="tree">
<ul>
<li>
a
<ul>
<li>a1</li>
<li>a2</li>
</ul>
</li>
<li>b</li>
</ul>
</div>
- 尝试写第二级元素.
// 首先判断第一级是否含有第二级元素
if(data[i].child){
var str = '<ul>';
for(let var j =0; i<data.[i].child.length; j++){
str += `<li>${data[i].child[j].name}</li>`
}
str += "</ul>";
$('ul').html(str)
}
- 可以发现.第二级的过程和第一级的过程是一样的.因此尝试使用递归如下:
$(function(){
function f(data){
var str = '<ul>'
for(let i =0; i<data.length; i++){
if(data[i].child){
// 含有孩子元素, 应该渲染成 <ul><li>a<ul><li>a1</li></ul></li></ul>的结构
str += `<li>${data[i].name}`
str += f(data[i].child)
str += "</li>"
} else {
str += `<li>${data[i].name}</li>`
}
}
str += "</ul>"
return str
}
$(".lists").html(f(data))
})
- 完成
添加事件
- 有时候左边的导航栏需要可以点击…
- 即,点击左侧的按钮, 导航栏可以进行收缩…
- 实现很简单.
- 在每个li下面添加一个span标签,利用jQuery的隐式迭代规则,给每个span标签添加一个点击事件.当鼠标点击上去的时候,判断当前span元素的兄弟元素是否有子元素
- 如果有就证明当前是可以展开的,否则不能展开
- 如果可以展开,则获取span中的内容.如果是
-
, 则将其变为+
并隐藏它的兄弟元素, - 如果是
+
,则当前的span变为-
,并显示其兄弟元素.
你可能用到的API
- 监听类tree下所有span的点击事件
- 获取当前被点击的对象
#('.tree li span').click(function(){
// 获取当前被点击的对象
console.log($(this))
})
- 获取当前元素的兄弟元素ul
- 判断该兄弟元素(ul)是否为空
$(this).siblings('ul')
if(this.siblings('ul').length == 0){
console.log('不能展开')
} else{
console.log('可以展开');
}
- 改变当前span中的内容
if($(this).html() == '-'){
$(this).html('+')
} else {
$(this).html('-')
}
总体代码
- 样式代码
ul li span {
display: inline-block;
width: 15px;
height: 15px;
color: red;
margin-right: 10px;
border: 1px solid #1890ff;
line-height: 15px;
text-align: center;
vertical-align: middle;
border-radius: 50%;
cursor: default;
}
li {
list-style-type: none;
}
li span:hover{
cursor: pointer;
}
- html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>无限级目录树</title>
<link rel="stylesheet" href="public/css/15.css" />
<script type="text/javascript" src="public/js/jquery.min.js"></script>
</head>
<body>
<div class="tree">
</div>
<script type="text/javascript" src="public/js/15.js"></script>
</body>
</html>
- js代码
data = [
{name: 'a', child:[
{name: 'a1'},
{name: 'a2', child: [{name:'a21'}]},
{name: 'a3', child: [
{name: 'a31'},
{name: 'a32'},
{name: 'a33'},
{name: 'a34', child: [
{name: 'a341'},
{name: 'a342'},
{name: 'a343'},
{name: 'a344'}
]}
]}
]},
{name: 'b'},
{name: 'c'}
]
$(function() {
function g(data) {
var str = '<ul>'
for (var i = 0; i < data.length; i++) {
if (data[i].child) {
str += `<li><span>-</span>${data[i].name}`
str += g(data[i].child);
str += "</li>"
} else {
str += `<li><span>-</span>${data[i].name}</li>`
}
}
str += '</ul>'
return str
}
// 渲染dom结构
$('.tree').html(g(data))
// 渲染完成后,给li下面的span添加点击事件
$('.tree li span').click(function(){
if($(this).siblings('ul').length >0){
console.log('可以展开')
if($(this).html() == '-'){
$(this).html('+')
$(this).siblings('ul').hide()
} else {
$(this).html('-');
$(this).siblings('ul').show();
}
} else {
console.log('不能展开')
}
})
})