隐藏

js的递归函数——实现可收放的树形菜单

发布:2024/12/1 9:57:41作者:管理员 来源:本站 浏览次数:180

递归函数实现树形菜单


   前言

   树形菜单的作用

   创建假数据或者请求接口数据

   定义递归函数,处理数据

   调用函数,渲染页面

   效果展示

   完整代码


前言


树形菜单是一种常见的网站导航方式,它通常由多个层级的菜单项组成,每个菜单项可以有子菜单项。在JavaScript中,我们可以使用递归函数来实现树形菜单。

树形菜单就是这样的东西,点击上一级,显示下一级,无限循环,一直逐层显示下一级。再次点击,关闭下一级。长的很像树,故名树形菜单。学会这个东西,是不是很酷?

在这里插入图片描述

树形菜单的作用


树形菜单的主要作用是将信息层次化,将复杂的信息结构变得更加清晰和直观。它通常用于展示层级关系比较复杂的数据,如文件目录、网站导航、商品分类等。树形菜单的优点包括:


       层次化展示:树形菜单可以将信息按照层级展示,使用户能够更加清晰地理解信息之间的关系。


       简洁明了:树形菜单的结构简单明了,能够有效地减少信息的冗余,提高页面的整体美观度。


       交互性强:树形菜单可以通过展开和收起节点的方式,使用户能够更加方便地获取所需信息。


       可扩展性好:树形菜单可以根据需要随时添加新的节点,具有很好的扩展性。


创建假数据或者请求接口数据


首先,我们需要一个数据结构来表示树形菜单,通常可以使用嵌套的对象或数组来表示。每个菜单项包含以下属性:


下面是一个假数据:


const menu = [{

label: '家人',

children: [{

label: '爹妈',

children: [{

label: '我',

children: []

}]

}]

},

{

label: '老师',

children: [{

label: '物理老师',

children: [{

label: '物理老师儿子',

children: []

}]

},

{

label: '化学老师',

children: [{

label: '化学老师儿子',

children: []

}]

}

]

},

{

label: '老板',

children: [{

label: '总经理',

children: [{

label: '领导1',

children: [{

label: '韩国分公司',

children: []

}]

},

{

label: '领导2',

children: [{

label: '日本分公司',

children: []

}]

}

]

}]

}

];


    


'

运行


定义递归函数,处理数据


接下来,我们可以定义一个递归函数来遍历这个数据源,并且为每个菜单项添加点击事件。


下面是一个递归函数实现:


function createMenu(menuData) {

const menuEl = document.createElement('ul');


menuData.forEach(item => {

const itemEl = document.createElement('li');

const labelEl = document.createElement('span');

labelEl.innerText = item.label;

itemEl.appendChild(labelEl);


if (item.children.length > 0) {

labelEl.addEventListener('click', () => {

if (itemEl.classList.contains('open')) {

itemEl.classList.remove('open');

itemEl.removeChild(itemEl.lastChild);

} else {

itemEl.classList.add('open');

const submenuEl = createMenu(item.children);

itemEl.appendChild(submenuEl);

}

});

}

menuEl.appendChild(itemEl);

});

return menuEl;

}




'

运行


调用函数,渲染页面


最后,我们可以调用这个函数来生成完整的树形菜单的HTML代码:


const menuEl = createMenu(menu);

document.body.appendChild(menuEl);


     


这里假设树形菜单的容器元素的ID为menu。我们先取出这个元素,然后将生成的HTML代码插入到这个元素的innerHTML属性中,即可显示出树形菜单。

效果展示


在这里插入图片描述

完整代码


<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8" />

<meta name="viewport" content="width=device-width, initial-scale=1">

<title></title>

<script src="./js/jquery-3.6.1.js"></script>

<style></style>

</head>

<body>

<script>

const menu = [{

label: '家人',

children: [{

label: '爹妈',

children: [{

label: '我',

children: []

}]

}]

},

{

label: '老师',

children: [{

label: '物理老师',

children: [{

label: '物理老师儿子',

children: []

}]

},

{

label: '化学老师',

children: [{

label: '化学老师儿子',

children: []

}]

}

]

},

{

label: '老板',

children: [{

label: '总经理',

children: [{

label: '领导1',

children: [{

label: '韩国分公司',

children: []

}]

},

{

label: '领导2',

children: [{

label: '日本分公司',

children: []

}]

}

]

}]

}

];


function createMenu(menuData) {

const menuEl = document.createElement('ul');


menuData.forEach(item => {

const itemEl = document.createElement('li');

const labelEl = document.createElement('span');

labelEl.innerText = item.label;

itemEl.appendChild(labelEl);


if (item.children.length > 0) {

labelEl.addEventListener('click', () => {

if (itemEl.classList.contains('open')) {

itemEl.classList.remove('open');

itemEl.removeChild(itemEl.lastChild);

} else {

itemEl.classList.add('open');

const submenuEl = createMenu(item.children);

itemEl.appendChild(submenuEl);

}

});

}


menuEl.appendChild(itemEl);

});


return menuEl;

}


const menuEl = createMenu(menu);

document.body.appendChild(menuEl);

</script>

</body>

</html>