原生js做树形菜单(详细注释+加简易版)

简介: 原生js做树形菜单(详细注释+加简易版)

效果图:

html

<div class="epiboly"></div>

css

body {
    background-color: #5e7987;
}
.epiboly {
    width: 50%;
    margin-left: 25%;
}
.structure {
    list-style: none;
    border: 0.1px solid #000;
    background-color: rgb(0, 300, 190);
}
.epiboly ul li {
    margin-top: 10px;
    display: flex;
    border-bottom: 0.1px solid;
}
.structure>div {
    margin-top: 10px;
    border-bottom: 0.1px solid #000;
}
.epiboly ul {
    list-style: none;
}
ul img {
    width: 16px;
    height: 16px;
}

js

// 请求过来数据
let xhr = new XMLHttpRequest();
xhr.open('get', 'js/sxcd.json', true);
xhr.send();
xhr.onreadystatechange = function () {
    if (xhr.readyState == 4 && xhr.status == 200) {
        let text = xhr.responseText;
        let data = JSON.parse(text);
        show(data);
    }
};
// 获取到渲染地方
let epiboly = document.getElementsByClassName('epiboly')[0];
// 生成一个用于拼接的空数组
let str = '';
// 默认首个为头并加上状态
let statuss = true;
// 渲染函数
function show(data) {
    // 先判断他的状态为什么
    if (statuss) {
        // 确认为开头
        str += '<ul>';
    } else {
        // 确认为下属,隐藏
        str += '<ul style="display:none">';
    }
    // 循环数组的长度次数
    for (let i = 0; i < data.length; i++) {
         // 循环判断每次拼接后它有没有附属,有就加img
       if(data[i].fusu){
        // 每循环一次就拼接上内容
        str += '<p></p>'+'<li>' + data[i].name + '<img src="../img/向下.png">' + '</li>';
        // 有的话就改为false
        statuss = false;
        // 并重新调用函数传参
        show(data[i].fusu);
    }else{
        str += '<p></p>'+'<li>'+ data[i].name +'</li>';
       }
    }
    // 拼接上结尾标签
    str += '</ul>';
    epiboly.innerHTML = str;
    return str;
}
// 根据点击显示与隐藏
epiboly.addEventListener('click', function (e) {
    console.log(e)
    // 如果点击的那个元素,有下级元素,就展开  nextSibling 
    // nodeName属性获得它的名称,但是属性名是大写,即LI  UL    console.log(e.target.nodeName);  
    let a = e.target.nextSibling;
    // 判断是否有子元素
    if (e.target.nextSibling != null) {
        // 确认获取到的是点击的那个li标签
        console.log(e.target.nextSibling);
        if (e.target.nodeName == 'LI' && a.nodeName == 'UL') {
            // 判断是否处于none
            if (a.style.display == "none") {
               a.style.display = "block";
            } else if (a.style.display == "block") {
                a.style.display = "none";
            }
        }
    }
})

json

[
    {
        "name": "昆虫",
        "fusu": [
            {
                "name": "带翅膀的",
                "fusu": [
                    {
                        "name": 100
                    },
                    {
                        "name": 200
                    },
                    {
                        "name": 300
                    }
                ]
            },
            {
                "name": "不带翅膀的"
            },
            {
                "name": "会游泳的",
                "fusu": [
                    {
                        "name": "10分钟"
                    },
                    {
                        "name": "20分钟"
                    },
                    {
                        "name": "一辈子"
                    }
                ]
            },
            {
                "name": "不会游泳的"
            }
        ]
    },
    {
        "name": "动物",
        "fusu": [
            {
                "name": "两只",
                "fusu": [
                    {
                        "name": "10千米/小时"
                    },
                    {
                        "name": "20千米/小时"
                    },
                    {
                        "name": "30千米/小时"
                    },
                    {
                        "name": "100千米/小时"
                    }
                ]
            },
            {
                "name": "四只",
                "fusu": [
                    {
                        "name": "10千米/小时"
                    },
                    {
                        "name": "20千米/小时"
                    },
                    {
                        "name": "30千米/小时"
                    },
                    {
                        "name": "100千米/小时"
                    }
                ]
            }
        ]
    }
]
相关文章
|
18天前
|
移动开发 前端开发 JavaScript
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
于辰在大学期间带领团队参考网易游戏官网的部分游戏页面,开发了一系列前端实训作品。项目包括首页、2021校园招聘页面和明日之后游戏页面,涉及多种特效实现,如动态图片切换和人物聚合效果。作品源码已上传至CSDN,视频效果可在CSDN预览。
29 0
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
|
2月前
|
移动开发 前端开发 JavaScript
原生JavaScript+canvas实现五子棋游戏_值得一看
本文介绍了如何使用原生JavaScript和HTML5的Canvas API实现五子棋游戏,包括棋盘的绘制、棋子的生成和落子、以及判断胜负的逻辑,提供了详细的代码和注释。
37 0
原生JavaScript+canvas实现五子棋游戏_值得一看
|
2月前
|
JSON JavaScript 前端开发
如何使用代码注释:关于JavaScript与TypeScript
TSDoc是一种标准化TypeScript代码文档注释的规范,使不同工具能无干扰地提取内容。它包括多种标记,如@alpha、@beta等发布阶段标记;@decorator、@deprecated等功能标记;@defaultValue、@eventProperty等描述标记;@example、@experimental等示例与实验性标记;@inheritDoc、@internal等引用与内部标记;@label、@link等链接标记;@override、@sealed等修饰符标记;以及@packageDocumentation、@param、
48 5
|
3月前
|
Devops 持续交付 测试技术
JSF遇上DevOps:开发流程将迎巨变?一篇文章带你领略高效协同的魅力!
【8月更文挑战第31天】本文探讨了如何在JavaServer Faces(JSF)开发中融入DevOps文化,通过持续集成与部署、自动化测试、监控与日志记录及反馈机制,提升软件交付速度与质量。文中详细介绍了使用Jenkins进行自动化部署、JUnit与Selenium进行自动化测试、ELK Stack进行日志监控的具体方法,并强调了持续改进的重要性。
39 0
|
3月前
|
JavaScript 前端开发 API
从零开始学表单操作,jQuery 与原生 JavaScript 完全指南,带你轻松掌握网页交互关键!
【8月更文挑战第31天】在网页开发中,表单是实现用户互动的关键元素。无论是收集信息、提交数据还是验证输入,都需要对表单进行有效操作。本文档介绍了如何使用原生 JavaScript 和 jQuery 操作表单,包括获取表单元素、读写表单值、处理表单提交及验证等核心功能。jQuery 提供了更简洁的语法和更好的兼容性,但原生 JavaScript 在性能上有优势。选择合适的方法取决于项目需求和个人偏好。下面通过具体示例展示了两种方式的操作方法。
39 0
|
5月前
|
JavaScript 前端开发
JavaScript 注释
JavaScript 注释
36 11
|
4月前
|
网络架构
若依修改 :id 不跳转注释的资料,路由配置:id不跳转修改,若依的store的permission.js对动态路由有控制
若依修改 :id 不跳转注释的资料,路由配置:id不跳转修改,若依的store的permission.js对动态路由有控制
若依修改 :id 不跳转注释的资料,路由配置:id不跳转修改,若依的store的permission.js对动态路由有控制
|
4月前
|
JavaScript
js 一键复制到剪贴板(原生js实现)
js 一键复制到剪贴板(原生js实现)
33 0
|
5月前
|
前端开发 JavaScript 容器
程序技术好文:纯原生javascript下拉框表单美化实例教程
程序技术好文:纯原生javascript下拉框表单美化实例教程
91 0
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
97 2