JavaScript樹(shù)形菜單功能實(shí)現(xiàn)方法總結(jié)
前言
在前端開(kāi)發(fā)中,樹(shù)形菜單是一種常見(jiàn)且實(shí)用的組件,它能夠以層級(jí)分明的結(jié)構(gòu)展示數(shù)據(jù),方便用戶(hù)快速瀏覽和操作。本文將詳細(xì)介紹如何使用 JavaScript 實(shí)現(xiàn)一個(gè)樹(shù)形菜單
功能示例:


一、數(shù)據(jù)獲取與解析
實(shí)現(xiàn)樹(shù)形菜單的第一步是獲取數(shù)據(jù)。在示例代碼中,我們使用XMLHttpRequest對(duì)象從本地 JSON 文件recursion.json中獲取數(shù)據(jù)。
let xhr = new XMLHttpRequest();
xhr.open('get', 'js/recursion.json', true);
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
let text = xhr.responseText;
// console.log(text);
data = JSON.parse(text);
// 將數(shù)據(jù)轉(zhuǎn)換為樹(shù)形,嵌套
let menudata = buildmenu(data, 0)
console.log(menudata);
// 接著獲取到頁(yè)面上的div,調(diào)用渲染函數(shù),輸出到頁(yè)面上
document.getElementsByClassName('items')[0].innerHTML = renders(menudata);
}
};上述代碼中,open方法用于初始化請(qǐng)求,參數(shù)分別為請(qǐng)求方法(get)、請(qǐng)求地址(js/recursion.json)和是否異步(true)。send方法發(fā)送請(qǐng)求,onreadystatechange事件監(jiān)聽(tīng)請(qǐng)求狀態(tài)變化,當(dāng)請(qǐng)求完成且狀態(tài)碼為 200 時(shí),將響應(yīng)文本通過(guò)JSON.parse方法解析為 JavaScript 對(duì)象,便于后續(xù)處理
二、數(shù)據(jù)處理:構(gòu)建樹(shù)形結(jié)構(gòu)
獲取到的數(shù)據(jù)通常是扁平化的,需要將其轉(zhuǎn)換為樹(shù)形結(jié)構(gòu),以便于展示。這一步通過(guò)遞歸函數(shù)buildmenu實(shí)現(xiàn):
// 這個(gè)是遞歸函數(shù),將數(shù)據(jù)展示的形式進(jìn)行改變
function buildmenu(data, pid) {
let result = [];
for (let i in data) {
if (data[i].pid == pid) {
result.push(data[i]);
result[result.length - 1].child = buildmenu(data, data[i].id);
}
}
return result;
}該函數(shù)接收兩個(gè)參數(shù):原始數(shù)據(jù)data和父節(jié)點(diǎn) IDpid。在循環(huán)遍歷數(shù)據(jù)過(guò)程中,篩選出父節(jié)點(diǎn) ID 與傳入的pid相同的節(jié)點(diǎn),將其添加到結(jié)果數(shù)組result中,并遞歸調(diào)用buildmenu函數(shù),將子節(jié)點(diǎn)構(gòu)建為樹(shù)形結(jié)構(gòu),賦值給當(dāng)前節(jié)點(diǎn)的child屬性。最終返回構(gòu)建好的樹(shù)形數(shù)據(jù)
三、頁(yè)面渲染:將數(shù)據(jù)轉(zhuǎn)換為 DOM 結(jié)構(gòu)
有了樹(shù)形數(shù)據(jù)后,需要將其渲染到頁(yè)面上。renders函數(shù)負(fù)責(zé)將樹(shù)形數(shù)據(jù)轉(zhuǎn)換為 HTML 字符串,并插入到頁(yè)面中:
function renders(data) {
let str = '';
for (let item of data) {
str += `<div class="box">`;
if (item.child.length > 0) {
str += `
<p class="title" onclick="click_toggle(this)">${item.name}</p>
<div style="display: none;" class="child">`;
str += renders(item.child);
str += `</div>`;
} else {
str += `<p class="title" onclick="get_self('${item.name}')">${item.name}</p>`;
}
str += `</div>`;
}
return str;
}renders函數(shù)同樣使用遞歸方式遍歷樹(shù)形數(shù)據(jù)。對(duì)于每個(gè)節(jié)點(diǎn),如果存在子節(jié)點(diǎn),則創(chuàng)建一個(gè)可展開(kāi) / 收起的標(biāo)題元素,并遞歸調(diào)用renders函數(shù)渲染子節(jié)點(diǎn);如果不存在子節(jié)點(diǎn),則直接創(chuàng)建一個(gè)普通標(biāo)題元素。最后將生成的 HTML 字符串返回,通過(guò)innerHTML屬性插入到頁(yè)面指定元素中。
四、交互功能實(shí)現(xiàn)
1. 展開(kāi)與收起
為了實(shí)現(xiàn)樹(shù)形菜單的展開(kāi)與收起功能,我們定義了click_toggle函數(shù):
function click_toggle(element){
let childitem=element.nextElementSibling
if(childitem.style.display==="block"){
childitem.style.display="none";
}
else{
childitem.style.display="block";
}
}
該函數(shù)接收一個(gè) DOM 元素(標(biāo)題元素)作為參數(shù),獲取其下一個(gè)兄弟元素(即子節(jié)點(diǎn)容器),根據(jù)子節(jié)點(diǎn)容器的顯示狀態(tài)切換其display屬性,從而實(shí)現(xiàn)展開(kāi)與收起效果。
2. 節(jié)點(diǎn)點(diǎn)擊事件
對(duì)于葉子節(jié)點(diǎn),我們定義了get_self函數(shù),用于處理節(jié)點(diǎn)點(diǎn)擊事件:
function get_self(self){
alert(self);
}在實(shí)際應(yīng)用中,可以根據(jù)需求將alert替換為更復(fù)雜的業(yè)務(wù)邏輯,例如跳轉(zhuǎn)到相關(guān)頁(yè)面、展示詳細(xì)信息等。
五、CSS 樣式美化
為了使樹(shù)形菜單在頁(yè)面上展示得更加美觀(guān),我們使用 CSS 對(duì)其進(jìn)行樣式定義:
body{
background-color: lightblue;
}
h1{
width: 100%;
text-align: center;
}
.items{
font-size: 20px;
color: white;
margin: 10px auto;
width: 40%;
min-height: 100vh;
}
.title{
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
/* display: none; */
}
.title:hover{
background-color: cornflowerblue;
}
.child{
width: 95%;
margin-left: 5%;
display: flex;
align-items: center;
justify-content: space-between;
}
.box{
width: 95%;
border-bottom: 1px solid;
margin-left: 5%;
margin-top: 10px;
}上述 CSS 代碼設(shè)置了頁(yè)面背景顏色、標(biāo)題樣式、菜單容器樣式、標(biāo)題元素樣式以及子節(jié)點(diǎn)容器樣式等,使樹(shù)形菜單在視覺(jué)上更加清晰和美觀(guān)。
六、總結(jié)與優(yōu)化方向
通過(guò)以上步驟,我們成功實(shí)現(xiàn)了一個(gè)功能完整的樹(shù)形菜單。從數(shù)據(jù)獲取、處理到頁(yè)面渲染和交互,每一個(gè)環(huán)節(jié)都緊密相連,共同構(gòu)成了一個(gè)實(shí)用的前端組件。
到此這篇關(guān)于JavaScript樹(shù)形菜單功能實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)js樹(shù)形菜單功能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
微信小程序?qū)崿F(xiàn)獲取用戶(hù)信息并存入數(shù)據(jù)庫(kù)操作示例
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)獲取用戶(hù)信息并存入數(shù)據(jù)庫(kù)操作,涉及微信小程序wx.request后臺(tái)數(shù)據(jù)交互及php數(shù)據(jù)存儲(chǔ)相關(guān)操作技巧,需要的朋友可以參考下2019-05-05
javascript實(shí)現(xiàn)掃雷簡(jiǎn)易版
這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)掃雷簡(jiǎn)易版,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-08-08
通過(guò)JavaScript腳本復(fù)制網(wǎng)頁(yè)上的一個(gè)表格
通過(guò)JavaScript腳本復(fù)制網(wǎng)頁(yè)上的一個(gè)表格...2006-07-07
JavaScript分水嶺CommonJS對(duì)比ES模塊分析
這篇文章主要為大家介紹了JavaScript分水嶺CommonJS對(duì)比ES模塊分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
JavaScript中Textarea滾動(dòng)條不能拖動(dòng)的解決方法
這篇文章主要介紹了JavaScript中Textarea滾動(dòng)條不能拖動(dòng)的解決方法,主要針對(duì)IE瀏覽器中Textarea滾動(dòng)條綁定了onfocus事件時(shí)分析對(duì)應(yīng)的處理方法,需要的朋友可以參考下2015-12-12
html的DOM中document對(duì)象anchors集合用法實(shí)例
這篇文章主要介紹了html的DOM中document對(duì)象anchors集合用法,實(shí)例分析了anchors集合的功能及使用技巧,需要的朋友可以參考下2015-01-01
讓網(wǎng)站自動(dòng)生成章節(jié)目錄索引的多個(gè)js代碼
這篇文章主要介紹了讓博客園博客自動(dòng)生成章節(jié)目錄索引的多個(gè)js代碼,需要的朋友可以參考下2018-01-01
js定時(shí)器不準(zhǔn)確問(wèn)題的解決方法
本文主要介紹了js定時(shí)器不準(zhǔn)確問(wèn)題的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06

