我們僅僅知道用戶點擊的那一條數(shù)據(jù),所以這條數(shù)據(jù)必須是唯一的才能構(gòu)建一顆唯一的樹結(jié)構(gòu),如果后端給不到你唯一的值,一定要讓他給你生成一個唯一值id

成都創(chuàng)新互聯(lián)公司專注于鷹潭企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè),購物商城網(wǎng)站建設(shè)。鷹潭網(wǎng)站建設(shè)公司,為鷹潭等地區(qū)提供建站服務(wù)。全流程定制網(wǎng)站設(shè)計,專業(yè)設(shè)計,全程項目跟蹤,成都創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務(wù)
我采用的string切割插入值
table初始化進來只有一層,并且是固定的
此時生成的是
樓主您好,樹形菜單要靠JavaScript來實現(xiàn),所以,您可以從網(wǎng)上找來JavaScript版的或者jquery版的樹形菜單然后放到您的aspx頁面里面
!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" ""
head
meta http-equiv="Content-Type" content="text/html; charset=utf-8"
meta name="author" content="心夢緣ocean ocl" /
titleMy tree demo/title
style type="text/css"
/*主頁面樣式*/
.leftNav {
? width: 20%;
? height:500px;
? border:#B9E0F7 1px solid;
? margin-left: 1%;
? margin-right: 1%;
}
#footer {
color:#808080;
line-height: 1.6em;
padding: 0 0 1em 0;
}
/*我的樹樣式表*/
.treeDiv {
color: #636363;
font-size: 14px;
font-weight: normal;
background-color: #fff;
color: black;
overflow: auto;
padding: 0 0 1em 0;
overflow-x: hidden;
}
.treeNode {
white-space: nowrap;
text-indent: -14px;
margin: 6px 2px 5px 14px;
}
a.treeUnselected:hover, a.treeSelected:hover {
background-color: #BFD9ED;
text-decoration: none;
}
a.treeUnselected, a.treeSelected {
color: black;
padding: 1px 3px 1px 0;
text-decoration: none;
}
a.treeSelected {
background-color: #B9E0F7;
}
a.treeUnselected {
background-color: transparent;
}
.treeSubnodes {
display: block;
}
.treeSubnodesHidden {
display: none;
}
.treeNode img.treeNoLinkImage, .treeNode img.treeLinkImage {
height: 15px;
margin-left: 5px;
margin-right: 0px;
width: 15px;
}
.treeNode img.treeLinkImage {
cursor: pointer;
}
div.treeNode a, div.treeNode span.apiRoot {
display: inline-block;
margin-left: 24px;
text-indent: 0;
white-space: normal;
width: 95%;
word-wrap: break-word;
}
div.treeNode span.category {
cursor: pointer;
}
/style
/head
body
div class="leftNav"
div id="samplesToc"
? div id="tree" style="top: 35px; left: 0px;" class="treeDiv"
? ? div id="treeRoot" onselectstart="return false" ondragstart="return false"
? ? ? div class="treeNode"
? ? ? ? img src="../graphics/treenodeplus.gif" onclick="expandCollapse(this.parentNode)" class="treeLinkImage"
? ? ? ? span onclick="expandCollapse(this.parentNode)" class="category"目錄節(jié)點一 /span
? ? ? ? div class="treeSubnodesHidden"
? ? ? ? ?
? ? ? ? ? ? div class="treeNode"
? ? ? ? ? ? ? ? ?img src="../graphics/treenodeplus.gif" onclick="expandCollapse(this.parentNode)" class="treeLinkImage"
? ? ? ? ? ? ? ? ?span onclick="expandCollapse(this.parentNode)" class="category"目錄節(jié)點一子目錄 /span
? ? ? ? ? ? ? ? ?div class="treeSubnodesHidden"
? ? ? ? ? ? ? ? ? ? ?div class="treeNode"
? ? ? ? ? ? ? ? ? ? ? ? a href="#" class="treeUnselected" onclick="clickAnchor(this)"二級葉子結(jié)點一/a
? ? ? ? ? ? ? ? ? /div
? ? ? ? ? ? ? ? ? div class="treeNode"
? ? ? ? ? ? ? ? ? ? ? ? a href="#" class="treeUnselected" onclick="clickAnchor(this)"二級葉子結(jié)點二/a
? ? ? ? ? ? ? ? ? /div
? ? ? ? ? ? ? /div
? ? ? ? ? ? /div
? ? ? ? ?
? ? ? ? ? div class="treeNode"
? ? ? ? ? ? a href="#" class="treeUnselected" onclick="clickAnchor(this)"葉子結(jié)點一/a
? ? ? ? ? /div
? ? ? ? ? div class="treeNode"
? ? ? ? ? ? a href="#" class="treeUnselected" onclick="clickAnchor(this)"葉子結(jié)點二/a
? ? ? ? ? /div
? ? ? ? ? div class="treeNode"
? ? ? ? ? ? a href="#" class="treeUnselected" onclick="clickAnchor(this)"葉子結(jié)點三/a
? ? ? ? ? /div
? ? ? ? ? div class="treeNode"
? ? ? ? ? ? a href="#" class="treeUnselected" onclick="clickAnchor(this)"葉子結(jié)點四/a
? ? ? ? ? /div
? ? ? ? ? div class="treeNode"
? ? ? ? ? ? a href="#" class="treeUnselected" onclick="clickAnchor(this)"葉子結(jié)點五/a
? ? ? ? ? /div
? ? ? ? ? div class="treeNode"
? ? ? ? ? ? a href="#" class="treeUnselected" onclick="clickAnchor(this)"葉子結(jié)點六/a
? ? ? ? ? /div
? ? ? ? /div
? ? ? /div
? ? ? !--end block--
? ? ? div class="treeNode"
? ? ? ? img src="../graphics/treenodeplus.gif" onclick="expandCollapse(this.parentNode)" class="treeLinkImage"
? ? ? ? span onclick="expandCollapse(this.parentNode)" class="category"目錄節(jié)點二/span
? ? ? ? div class="treeSubnodesHidden"
? ? ? ? ? div class="treeNode"
? ? ? ? ? ? a href="#" class="treeUnselected" onclick="clickAnchor(this)"葉子結(jié)點一/a
? ? ? ? ? /div
? ? ? ? ? div class="treeNode"
? ? ? ? ? ? a href="#" class="treeUnselected" onclick="clickAnchor(this)"葉子結(jié)點二/a
? ? ? ? ? /div
? ? ? ? ? div class="treeNode"
? ? ? ? ? ? a href="#" class="treeUnselected" onclick="clickAnchor(this)"葉子結(jié)點三/a
? ? ? ? ? /div
? ? ? ? ? div class="treeNode"
? ? ? ? ? ? a href="#" class="treeUnselected" onclick="clickAnchor(this)"葉子結(jié)點四/a
? ? ? ? ? /div
? ? ? ? ? div class="treeNode"
? ? ? ? ? ? a href="#" class="treeUnselected" onclick="clickAnchor(this)"葉子結(jié)點五/a
? ? ? ? ? /div
? ? ? ? /div
? ? ? /div
? ? ? !--end block--
? ? /div
? /div
/div !-- end samplesToc --
/div !-- end leftNav --
div class="right content"
/div!-- end main ?content--
div id="footer" align="center"
?
/div!-- end footer--
script type="text/javascript"
var treeSelected = null;//選中的樹節(jié)點
var imgPlus = new Image();
imgPlus.src="../graphics/treenodeplus.gif";
var imgMinus = new Image();
imgMinus.src="../graphics/treenodeminus.gif";
//父節(jié)點展開事件
function expandCollapse(el)
{
//如果父節(jié)點有字節(jié)點(class 屬性為treeSubnodesHidden),展開所有子節(jié)點
if (el.className!= "treeNode"){
? return; ? ?//判斷父節(jié)點是否為一個樹節(jié)點,如果樹節(jié)點不能展開,請檢查是否節(jié)點的class屬性是否為treeNode
} ?
var child;
var imgEl;//圖片子節(jié)點,在樹展開時更換圖片
for(var i=0; i el.childNodes.length; i++)
{
? child = el.childNodes[i];
? if (child.src)
? {
? ? ? imgEl = child;
? }
? else if (child.className == "treeSubnodesHidden")
? {
? ? ? child.className = "treeSubnodes";//原來若隱藏,則展開
? ? ? imgEl.src = imgMinus.src;//更換圖片
? ? ? break;
? }
? else if (child.className == "treeSubnodes")
? {
? ? ? child.className = "treeSubnodesHidden";//原來若展開,則隱藏
? ? ? imgEl.src = imgPlus.src;//更換圖片
? ? ? break;
? }
}
}
//子節(jié)點點擊事件,設(shè)置選中節(jié)點的樣式
function clickAnchor(el)
{
selectNode(el.parentNode);
el.blur();
}
function selectNode(el)
{
if (treeSelected != null)
{
? setSubNodeClass(treeSelected, 'A', 'treeUnselected');
}
setSubNodeClass(el, 'A', 'treeSelected');
treeSelected = el;
}
function setSubNodeClass(el, nodeName, className)
{
var child;
for (var i=0; i el.childNodes.length; i++)
{
? child = el.childNodes[i];
? if (child.nodeName == nodeName)
? {
? ? ? child.className = className;
? ? ? break;
? }
}
}
/script
/body
/html
運行效果:
頁面既然得到從服務(wù)器傳過來的json數(shù)據(jù)之后,還要轉(zhuǎn)換為Object
比如,服務(wù)器組裝好的json數(shù)據(jù):
{
id:'001',
nodeMsg:'節(jié)點1'
}
這個是ajax成功之后的回調(diào)
function(xhr){
var o = eval('(' + xhr.responseText + ')');
alert(o.id + ':' + o.nodeMsg);
}
// 生成樹結(jié)構(gòu)
function tree(list) {
const result = [];
for (let value of list) {
// 排除空字符串的情況
if (!value) {
continue;
}
const values = value.split('/');
// 查找樹結(jié)構(gòu)的當前級別是否已經(jīng)存在,不存在則創(chuàng)建對象,并添加入列表。
let current = result.find(item = item.name === values[0]);
if (current === void 0) {
current = {};
result.push(current);
}
for (let i = 0, length = values.length; i length; i++) {
current.name = values[i];
if (i length - 1) {
// 如果還有下一級內(nèi)容,判斷當前是否有 children,沒有則構(gòu)建.
if (current.children === void 0) {
current.children = [];
}
// 查找下一級對象,為下一遍遍歷構(gòu)建對象
let nextCurrent = current.children.find(item = item.name === values[i + 1]);
if (nextCurrent === void 0) {
nextCurrent = {};
current.children.push(nextCurrent);
}
current = nextCurrent;
}
}
}
return result;
}
============ 假裝分割線 ===========
以上代碼是生成樹的函數(shù),調(diào)用 tree 函數(shù)并傳入你的 input 數(shù)據(jù),返回值就是生成的樹。百科沒找到傳代碼的地方了。
title: JS樹結(jié)構(gòu)數(shù)據(jù)的遍歷
date: 2022-04-14
description: 針對項目中出現(xiàn)樹形結(jié)構(gòu)數(shù)據(jù)的時候,我們怎樣去操作他
項目中我們會經(jīng)常出現(xiàn)對樹形結(jié)構(gòu)的遍歷、查找和轉(zhuǎn)換的場景,比如說DOM樹、族譜、社會機構(gòu)、組織架構(gòu)、權(quán)限、菜單、省市區(qū)、路由、標簽等等。那針對這些場景和數(shù)據(jù),我們又如何去遍歷和操作,有什么方式或者技巧可以簡化我們的實現(xiàn)思路。下面我們將針對常規(guī)出現(xiàn)的場景去總結(jié)一下我們的遍歷方式
樹的特點
1、每個節(jié)點都只有有限個子節(jié)點或無子節(jié)點;
2、沒有父節(jié)點的節(jié)點稱為根節(jié)點;
3、每一個非根節(jié)點有且只有一個父節(jié)點;
4、除了根節(jié)點外,每個子節(jié)點可以分為多個不相交的子樹;
5、樹里面沒有環(huán)路
下面的圖片表示一顆樹
在下面的JS中我們由多棵樹組成我們的數(shù)據(jù)
在這數(shù)據(jù)中我們?nèi)绾卧u判數(shù)據(jù)是否為葉節(jié)點(也就是最后一級),我們每個節(jié)點都會存在children屬性,如果不存在children屬性或者children不是一個數(shù)組或者children為數(shù)組且長度為0我們則認為他是一個葉節(jié)點
我們針對樹結(jié)構(gòu)的操作離不開遍歷,遍歷的話又分為廣度優(yōu)先遍歷、深度優(yōu)先遍歷。其中深度優(yōu)先遍歷可以通過遞歸和循環(huán)的方式實現(xiàn),而廣度優(yōu)先遍歷的話是非遞歸的
從上往下對每一層依次訪問,在每一層中,從左往右(也可以從右往左)訪問結(jié)點,訪問完一層就進入下一層,直到?jīng)]有結(jié)點可以訪問為止。即訪問樹結(jié)構(gòu)的第n+1層前必須先訪問完第n層。
簡單的說,BFS是從根節(jié)點開始,沿著樹的寬度遍歷樹的節(jié)點。如果所有節(jié)點均被訪問,則算法中止。
所以我們的實現(xiàn)思路是,維護一個隊列,隊列的初始值為樹結(jié)構(gòu)根節(jié)點組成的列表,重復(fù)執(zhí)行以下步驟直到隊列為空:
取出隊列中的第一個元素,進行訪問相關(guān)操作,然后將其后代元素(如果有)全部追加到隊列最后。
深度優(yōu)先搜索算法(英語:Depth-First-Search,DFS)是一種用于遍歷或搜索樹或圖的算法。這個算法會盡可能深的搜索樹的分支。當節(jié)點v的所在邊都己被探尋過,搜索將回溯到發(fā)現(xiàn)節(jié)點v的那條邊的起始節(jié)點。這一過程一直進行到已發(fā)現(xiàn)從源節(jié)點可達的所有節(jié)點為止。如果還存在未被發(fā)現(xiàn)的節(jié)點,則選擇其中一個作為源節(jié)點并重復(fù)以上過程,整個進程反復(fù)進行直到所有節(jié)點都被訪問為止
1、先序遍歷
訪問子樹的時候,先訪問根再訪問根的子樹
2、后序遍歷
訪問子樹的時候,先訪問子樹再訪問根
1、先序遍歷
先序遍歷與廣度優(yōu)先循環(huán)實現(xiàn)類似,要維護一個隊列,不同的是子節(jié)點不追加到隊列最后,而是加到隊列最前面
2、后序遍歷
后序遍歷就略微復(fù)雜一點,我們需要不斷將子樹擴展到根節(jié)點前面去,執(zhí)行列表遍歷,并且通過一個臨時對象維護一個id列表,當遍歷到某個節(jié)點如果它沒有子節(jié)點或者它本身已經(jīng)存在于我們的臨時id列表,則執(zhí)行訪問操作,否則繼續(xù)擴展子節(jié)點到當前節(jié)點前面
對于樹結(jié)構(gòu)的遍歷操作,其實遞歸是最基礎(chǔ),也是最容易理解的。遞歸本身就是循環(huán)的思想,所以可以用循環(huán)來改寫遞歸,以上的方式在項目中已經(jīng)廊括了大部分的場景了,我們在日常開發(fā)中可以根據(jù)場景或者需要去選擇我們的遍歷方式,或者基于此對他進行調(diào)整和優(yōu)化,至于每種方式的空間復(fù)雜度和時間復(fù)雜度我們在這個地方就不去嘗試了,各位感興趣可以自己去驗證。
廣度優(yōu)先搜索
樹的遍歷
深度優(yōu)先搜索
圖文詳解兩種算法:深度優(yōu)先遍歷(DFS)和廣度優(yōu)先遍歷(BFS)
二叉樹遍歷(前序,后序,中序,層次)遞歸與迭代實現(xiàn)JavaScript
JS樹結(jié)構(gòu)操作:查找、遍歷、篩選、樹和列表相互轉(zhuǎn)換
新聞名稱:javascript樹表,js語法樹
URL鏈接:http://chinadenli.net/article27/dsicccj.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站、網(wǎng)站排名、自適應(yīng)網(wǎng)站、搜索引擎優(yōu)化、企業(yè)網(wǎng)站制作、虛擬主機
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)