算法 --- > 递归实现多级树展开结构

说明

  • 先根据数据渲染,然后再实现事件

渲染

  • 在项目中,经常会给出一个深度不确定的数组,数字结构如下:
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('不能展开')
    }

  })

})

参考

源代码

发布了228 篇原创文章 · 获赞 41 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/piano9425/article/details/104226321
今日推荐