<!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": "性能和安全的優化"
}
]
}]