JavaScript小案例-树形菜单(菜单数据为数组)

菜单层级理论上可以无限多,因为是递归渲染。

gif演示图:
在这里插入图片描述
代码:
树形菜单.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>树形菜单-数组</title><style>* {padding: 0;margin: 0;box-sizing: border-box;font-size: 14px;color: #fff;}body {background-color: #222;}.aside-menu {position: fixed;padding: 20px;width: 300px;height: 700px;background-color: #333;overflow: auto;}ul {list-style: none;}.aside-menu a {display: block;text-decoration: none;height: 30px;line-height: 30px;}.active {color: #00ff30;}.aside-menu a:hover {background-color: #727171;}[data-childs]::after {content: '-';float: right;}.expand::after {content: '+';float: right;}.notdisplay {display: none;}</style>
</head><body><div class="aside-menu"><ul class="menuwrapper"></ul></div><script>// 菜单数据集合let menuArray = [{id: '0',//菜单idname: '树形菜单',//菜单名submenu: [//子菜单集合{id: '0',name: '菜单',submenu: [{id: '0',name: '菜单',submenu: [{id: '0',name: '菜单',submenu: []},{id: '0',name: '菜单',submenu: [{id: '0',name: '菜单',submenu: []}, {id: '0',name: '菜单',submenu: []}, {id: '0',name: '菜单',submenu: []}, {id: '0',name: '菜单',submenu: []},]},]},]},]},{id: '0',name: '菜单',submenu: [{id: '0',name: '菜单',submenu: []},]},{id: '0',name: '菜单',submenu: []}, {id: '0',name: '菜单',submenu: []}, {id: '0',name: '菜单',submenu: []}, {id: '0',name: '菜单',submenu: []}, {id: '0',name: '菜单',submenu: []}, {id: '0',name: '菜单',submenu: []}, {id: '0',name: '菜单',submenu: []}, {id: '0',name: '菜单',submenu: [{id: '0',name: '菜单',submenu: []}, {id: '0',name: '菜单',submenu: []}, {id: '0',name: '菜单',submenu: [{id: '0',name: '菜单',submenu: []}, {id: '0',name: '菜单',submenu: []},]},]}, {id: '0',name: '菜单',submenu: []}, {id: '0',name: '菜单',submenu: []},]/*** menuData-菜单数组* menuwrapper-当前菜单项包裹盒子* level-菜单层级,L0,L1,L2,...* paddingLeft-当前菜单的子菜单左内边距,制造树形缩进效果* paddingLeftIncrement-每层菜单左内边距增加值,默认20(px)*/function renderMenu(menuData, menuwrapper, level = 0, paddingLeft = 0, paddingLeftIncrement = 20) {if (menuData && menuData.length > 0) {let l = levelmenuwrapper.classList.add(`L${l}`)menuwrapper.style.paddingLeft = `${paddingLeft}px`for (let i = 0; i < menuData.length; i++) {/** * <ul class="menuwrapper">*  <li class="menuitem">*   <a href="#" data-childs="3" class="expand"><span class="active">菜单名</span>::after</a>*   <ul class="notdisplay">*    </ul>*  </li>* </ul>*/const menuItem = document.createElement('li')menuItem.classList.add('menuitem')const link = document.createElement('a')link.href = '#'link.innerHTML = `<span>${menuData[i].name}</span>`menuItem.appendChild(link)menuwrapper.appendChild(menuItem)const submenu = menuData[i].submenuif (submenu.length > 0) {l++link.dataset.childs = submenu.lengthconst submenuWrapper = document.createElement('ul')// 展开折叠图标切换、子菜单显示隐藏切换link.addEventListener('click', () => {link.classList.toggle('expand')link.nextElementSibling.classList.toggle('notdisplay')})paddingLeft = paddingLeftIncrement// 递归渲染子菜单数组renderMenu(submenu, submenuWrapper, l, paddingLeft)menuItem.appendChild(submenuWrapper)}}}}const menuwrapper = document.querySelector('.menuwrapper')// 活跃菜单menuwrapper.addEventListener('click', (e) => {if (e.target.tagName === 'A') {let activeLink = document.querySelector('.active')if (activeLink) activeLink.classList.remove('active')e.target.firstElementChild.classList.add('active')}})// 渲染renderMenu(menuArray, menuwrapper)// 释放菜单数据menuArray = null</script>
</body></html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/137896.html

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

相关文章

spring boot项目一次性能测试的总结

满足标准&#xff1a;并发大于等于100 &#xff0c;平均响应时间小于等于3秒 项目在压测过程中并发数只有50&#xff0c;在并发数100的情况下有很多请求链接是失败的 我们该如何入手去处理这些问题并提高并发数呢&#xff1f; 1、首先从压测结果入手&#xff0c;对不满足标准…

7.algorithm2e中while怎么使用

algorithm2e中while怎么使用 在 algorithm2e 宏包中&#xff0c;要使用 while 循环&#xff0c;您可以使用 \While 和 \EndWhile 命令来定义循环的开始和结束。以下是如何使用 while 循环的示例&#xff1a; \documentclass{article} \usepackage[linesnumbered,boxed]{algorit…

GMAC PHY介绍

1.1PHY接口发展 &#xff08;1&#xff09;MII支持10M/100Mbps&#xff0c;一个接口由14根线组成&#xff0c;它的支持还是比较灵活的&#xff0c;但是有一个缺点是因为它一个端口用的信号线太多。参考芯片&#xff1a;DP83848 、DM900A&#xff08;该芯片内部集成了MAC和PHY接…

nginx配置gzip压缩,优化传输效率,加快页面访问速度

文章目录 引言一、什么是nginx的gzip二、nginx的常用配置项三、使用示例四、浏览器查看gzip是否生效1. 判断浏览器是否支持gzip2. 判断gzip是否生效 总结 引言 在现代互联网的高速发展进程中&#xff0c;网站的访问速度愈发成为了用户选择和留存的关键。其中&#xff0c;通过g…

python小程序 图书馆图书借阅借还管理系统 mbc21

为设计一个安全便捷&#xff0c;并且使借阅者更好获取本图书借还信息&#xff0c;本文主要有安全、简洁为理念&#xff0c;实现借阅者快捷寻找图书借还信息&#xff0c;从而解决图书借还信息复杂难辨的问题。该系统以django架构技术为基础&#xff0c;采用python语言和MySQL数据…

如何从外网远程控制企业内网电脑?

在企业中&#xff0c;保护公司机密和数据安全是至关重要的。为了确保员工在使用公司电脑时遵守相关规定&#xff0c;许多公司会采取外网监控员工电脑的方法。本文将介绍一些真实有效的方法和具体的操作步骤&#xff0c;以帮助您更好地监控员工电脑。 一、什么是外网监控&#x…

Android 中集成 TensorFlow Lite图片识别

在上图通过手机的相机拍摄到的物体识别出具体的名称&#xff0c;这个需要通过TensorFlow 训练的模型引用到项目中&#xff1b;以下就是详细地集成 TensorFlow步骤&#xff0c;请按照以下步骤进行操作&#xff1a; 在项目的根目录下的 build.gradle 文件中添加 TensorFlow 的 Ma…

GitStats - 统计Git所有提交记录工具

如果你是研发效能组的一员或者在从事 CI/CD 或 DevOps&#xff0c;除了提供基础设施&#xff0c;指标和数据是也是一个很重要的一环&#xff0c;比如需要分析下某个 Git 仓库代码提交情况&#xff1a; 该仓库的代码谁提交的代码最多 该仓库的活跃度是什么样子的 各个时段的提交…

视频去LOGO的方法,AI自动完美地去除视频LOGO

喜欢做影视剧剪辑的朋友&#xff0c;可能会遇到下载的影视剧本身存在字幕、台标的情况&#xff0c;这些和新的剪辑主题不相符的原片元素&#xff0c;都会影响我们最终的成片效果。不过也无需烦恼哦&#xff0c;我们可以利用AI视频处理工具&#xff0c;自动去除视频中的logo或其…

数据结构-leetcode-移除元素

int removeElement(int* nums, int numsSize, int val){int start0;int end0;int flag0;for(int i 0;i<numsSize;i){if(nums[end]val){end;flag;}else if(nums[end]!val){nums[start]nums[end];end;start;}}return numsSize-flag; } 注&#xff1a;时间复杂度为O(N)&#xf…

Unity——对象池

对象池是一种朴素的优化思想。在遇到需要大量创建和销毁同类物体的情景时&#xff0c;可以考虑使用对象池技术优化游戏性能。 一、为什么要使用对象池 在很多类型的游戏中都会创建和销毁大量同样类型的物体。例如&#xff0c;飞行射击游戏中有大量子弹&#xff0c;某些动作游戏…

ClickHouse面向列的数据库管理系统(原理简略理解)

目录 官网 什么是Clickhouse 什么是OLAP 面向列的数据库与面向行的数据库 特点 为什么面向列的数据库在OLAP场景中工作得更好 为什么ClickHouse这么快 真实的处理分析查询 OLAP场景的关键属性 引擎作用 ClickHouse引擎 输入/输出 CPU 官网 https://clickhouse.com…

【人工智能】企业如何使用 AI与人工智能的定义、研究价值、发展阶段的深刻讨论

前言 人工智能&#xff08;Artificial Intelligence&#xff09;&#xff0c;英文缩写为AI。 它是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。人工智能是新一轮科技革命和产业变革的重要驱动力量。 &#x1f4d5;作者简介&#x…

PLC串口通讯和通讯接口知识汇总

在使用PLC的时候会接触到很多的通讯协议以及通讯接口&#xff0c;最基本的PLC串口通讯和基本的通讯接口你都了解吗&#xff1f; 一、什么是串口通讯&#xff1f; 串口是一种接口标准&#xff0c;是计算机上一种非常通用设备通信的协议。它规定了接口的电气标准&#xff0c;没…

【C#】FileInfo类 对文件进行操作

提示&#xff1a;使用FileInfo类时&#xff0c;要引用System.IO命名空间。 using System.IO; FileInfo类 生成文件删除文件移动文件复制文件获取文件名判断文件是否存在属性列表其它常用方法 生成文件 Create()&#xff1a;在指定路径上创建文件。 FileInfo myFile new FileIn…

SOLIDWORKS Composer位置关键帧的使用

SOLIDWORKS Composer是专业的SOLIDWORKS及3D文件处理的动画制作软件&#xff0c;作为SOLIDWORKS 产品线下的一个明星存在。 SOLIDWORKS Composer几乎可以处理任何SOLIDWORKS的模型文件并将之转化成可以动作的机械动画&#xff0c;可以引用在企业的网站、产品说明书以及工作指导…

二分与前缀和

目录 &#x1f348;前言 ❤二分 &#x1f339;二分 &#x1f33c;数的范围 &#x1f33c;数的三次方根 &#x1f33c;特殊数字 &#x1f33c;机器人跳跃问题 &#x1f33c;四平方和 &#x1f33c;分巧克力 &#x1f339;前缀和 &#x1f33c;前缀和 &#x1f33c;子…

深入理解CI/CD流程:改变你的开发生命周期

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

SAP CRM 模块:概述,体系结构

前言 CRM 代表“客户关系管理”&#xff0c;是一组有助于以有组织的方式管理客户关系的方法和工具。 在当今竞争激烈的商业环境中&#xff0c;顶级公司的注意力越来越集中于其最有价值的资产– 客户。 因此&#xff0c;这些公司需要一种合适的软件解决方案来迎合其客户&#…

Grafana设置默认主页

点击【设置/管理】-> 【默认首选项 Preferences】-> 【主页仪表盘】 在下拉中选择一个页面作为主页即可