選單產生方式
遞迴
by ph822720355
HTML
<ul id="menu"></ul>
JavaScript
// [全域變數] 假資料
const mockData = [
{ id: '1', parentId : '0', label: '基本功能', url: 'homepage/index' },
{ id: '2', parentId : '1', label: '使用者管理', url: 'subpage1/index' },
{ id: '3', parentId : '1', label: '權限管理', url: 'subpage2/index' },
{ id: '4', parentId : '0', label: '進階功能', url: 'homepage/index' },
{ id: '5', parentId : '4', label: '債務試算', url: 'subpage1/index' },
{ id: '6', parentId : '4', label: '報表', url: 'subpage2/index' },
{ id: '7', parentId : '6', label: '列印', url: 'subpage2/index' },
];
// [全域變數] Menu
let globalMenuList = [];
/* [方法] 建立Menu */
function buildMenuTree(flatData, includeRoot = true) {
// 定義根節點
const root = {
label: '目錄清單',
id: 0,
parentId: null,
children: []
};
// 創建一個物件,以id為鍵來存放每一個節點,方便後續直接查找節點
const nodesById = {};
// 一次遍歷來構建nodesById和初始化節點
flatData.forEach(item => {
nodesById[item.id] = {
...item,
routUrl: `Controller/${item.url}`,
children: []
};
});
// 遍歷所有節點,將它們放到適當的父節點或根節點下
flatData.forEach(item => {
const node = nodesById[item.id];
if (item.parentId === '0') {
root.children.push(node);
} else if (nodesById[item.parentId]) {
nodesById[item.parentId].children.push(node);
}
});
// 若includeRoot為true,回傳包含根節點的陣列;否則僅回傳根節點的子節點
return includeRoot ? [root] : root.children;
}
// [方法] 遞迴函數來建立HTML清單
function createMenuList(items) {
const ul = document.createElement('ul');
items.forEach(item => {
const li = document.createElement('li');
const a = document.createElement('a');
a.href = item.url;
a.textContent = item.label;
li.appendChild(a);
if (item.children && item.children.length > 0) {
const childUl = createMenuList(item.children);
li.appendChild(childUl);
}
ul.appendChild(li);
});
return ul;
}
// 取得不包含 根結點 的選單
globalMenuList = buildMenuTree(mockData, false)
// 取得不包含...