<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
a{
text-decoration: none;
}
.container{
box-sizing: border-box;
margin: 20px auto;
padding: 10px;
width: 600px;
border: 1px dashed #AAA;
}
.level{
display: none;
font-size: 14px;
margin-left: 10px;
}
.level.level0{
display: block;
margin-left: 0;
list-style: none;
}
.level li{
position: relative;
padding-left: 15px;
line-height: 30px;
list-style: none;
}
.level li .icon{
position: absolute;
left: 0;
top: 10px;
box-sizing: border-box;
width: 12px;
height: 12px;
line-height: 8px;
text-align: center;
border: 1px solid #AAA;
background: #EEE;
cursor: pointer;
}
.level li .icon::after{
display: block;
content: "+";
font-size: 12px;
font-style: normal;
}
.level li .open::after{
content: "-";
}
.level li .title{
color: #000;
}
</style>
</head>
<body>
<div class="container">
<ul class="level level0">
<!-- <li>
<a href="" class="title">前端开发</a>
<em class="icon open"></em>
<ul class="level level1" style="display: block;">
<li>
<a href="" class="title">HTML5核心知识</a>
</li>
</ul>
</li> -->
</ul>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<script>
/**
* 无限极菜单
*/
function queryData(){
return new Promise(resolve=>{
$.ajax({
url:'./data.json',
method:'get',
dataType:'json',
success:result=>{
resolve(result);
}
})
})
}
$(async function(){
let $level = $('.level');
// 获取数据
let result = await queryData();
// console.log(result);
// 数据绑定
let n=0;
let bindHTML = function bindHTML(result){
let str = ``;
n++;
result.forEach((item,index) => {
let {name,open,children} = item;
str +=`<li>
<a href="" class="title">${name}</a>
${children && children.length > 0 ?`
<em class="icon ${open ? 'open' : ''}"></em>
<ul class="level level${n}" style="display: ${open ? 'block' : 'none'};">
${bindHTML(children)}
</ul>`
: '' }
</li>
`;
});
n--;
return str;
}
$level.html(bindHTML(result));
// 点击 +/- 控制当前级别的显示隐藏
// 给当前树形菜单当中全部按钮绑定点击事件 -> 事件委派操做
$level.click(function(ev){
// 获取事件源:点击的谁,事件源就是谁
let target = ev.target,
$target = $(target);
// 点击的是 em
if(target.tagName === 'EM'){
let $ul = $target.next('ul');
$ul.stop().slideToggle(200);
$target.toggleClass('open');
}
});
})
</script>
</body>
</html>
----------------------data.json------------
[{
"name": "前端开发基础",
"open": true,
"children": [{
"name": "HTML5核心知识",
"children": [{
"name": "新增语义化标签"
},
{
"name": "表单元素新特性"
},
{
"name": "音视屏处理"
},
{
"name": "canvas和webGL"
},
{
"name": "新增JS中的API"
}
]
},
{
"name": "CSS3核心知识",
"children": [{
"name": "新增选择器"
},
{
"name": "字体图标"
},
{
"name": "经常使用的样式属性"
},
{
"name": "背景的处理"
},
{
"name": "transform变形"
},
{
"name": "CSS3动画",
"children": [{
"name": "transition过分动画"
},
{
"name": "animation帧动画"
},
{
"name": "3D动画的处理"
}
]
},
{
"name": "新盒子模型属性",
"children": [{
"name": "flex弹性盒子模型"
},
{
"name": "box-sizing新盒子模型属性"
},
{
"name": "cloumns多列布局"
}
]
}
]
},
{
"name": "实战案例和布局技巧",
"children": [{
"name": "实战案例练习",
"children": [{
"name": "居中处理"
},
{
"name": "同行排列"
},
{
"name": "圣杯布局"
},
{
"name": "双飞翼布局"
},
{
"name": "滑动门"
},
{
"name": "面包屑导航"
}
]
},
{
"name": "响应式布局开发",
"children": [{
"name": "viewport和dpi适配"
},
{
"name": "@media媒体查询"
},
{
"name": "rem等比缩放"
},
{
"name": "百分比布局"
}
]
}
]
}
]
}, {
"name": "前端开发核心",
"children": [{
"name": "JS(ES6)核心",
"children": [{
"name": "基础知识"
},
{
"name": "闭包做用域及堆栈内存"
},
{
"name": "面向对象和THIS处理"
},
{
"name": "同步异步(事件循环、微任务、宏任务)"
},
{
"name": "DOM事件和事件委托"
},
{
"name": "设计模式"
}
]
},
{
"name": "AJAX先后端交互",
"children": [{
"name": "AJAX基础知识"
},
{
"name": "跨域策略请求"
},
{
"name": "TCP协议相关基础知识"
},
{
"name": "性能和安全的初步优化"
},
{
"name": "经常使用的AJAX库和插件"
}
]
},
{
"name": "底层原理和高阶JS函数",
"children": [{
"name": "函数柯里化"
},
{
"name": "compos函数"
},
{
"name": "惰性思想"
},
{
"name": "组件插件封装"
},
{
"name": "底层源码解读"
}
]
}
]
}, {
"name": "前端工程化",
"children": [{
"name": "VUE全家桶",
"children": [{
"name": "基础知识"
},
{
"name": "MVVM实现原理"
},
{
"name": "路由处理"
},
{
"name": "vuex公共状态管理"
},
{
"name": "element-ui组件应用和二次封装"
}
]
},
{
"name": "REACT全家桶",
"children": [{
"name": "基础知识"
},
{
"name": "MVC实现原理"
},
{
"name": "DOM DIFF"
},
{
"name": "Virtual DOM"
},
{
"name": "路由处理"
},
{
"name": "公共状态管理",
"children": [{
"name": "REACT-REDUX、DAVS/SAGA等"
},
{
"name": "compos函数"
},
{
"name": "惰性思想"
},
{
"name": "组件插件封装"
},
{
"name": "底层源码解读"
}
]
},
{
"name": "高阶租价"
},
{
"name": "antd组件应用和二次封装"
}
]
},
{
"name": "底层原理和高阶JS函数",
"children": [{
"name": "函数柯里化"
},
{
"name": "compos函数"
},
{
"name": "惰性思想"
},
{
"name": "组件插件封装"
},
{
"name": "底层源码解读"
}
]
},
{
"name": "工程化开发部署",
"children": [{
"name": "webpack"
},
{
"name": "git"
},
{
"name": "linux"
}
]
}
]
}, {
"name": "前端开发热门点",
"children": [{
"name": "TypeScript"
},
{
"name": "flutter"
},
{
"name": "react native"
},
{
"name": "小程序"
},
{
"name": "性能和安全的优化"
}
]
}]