這個效果應該不算什麼稀奇,網上也有現成的代碼,我這個也沒什麼特別的地方,只是因為我自己寫的,也算是為學習DOM後一個練習;在IE下測試通過;
(最近又寫了一個,當然不再是為了練習;請參看:javascript操作xml產生樹形菜單(一)描述)
實現效果是這樣的:
讀取XML文檔;
採用遞迴產生無限級的樹形菜單;
能夠響應滑鼠事件,展開與拆疊子級菜單;
首先是產生一個XML文檔,我用的是XML Spy的編輯器;
<?xml version="1.0" encoding="utf-8"?>
<menu>
<menu name="明星名人">
<menu name="華人明星" url="">
<menu name="大陸新秀" url="">
<menu name="周筆暢" url="http://post.baidu.com/f?kw=%D6%DC%B1%CA%B3%A9" target="_blank"/>
<menu name="周筆暢" url="http://post.baidu.com/f?kw=%D6%DC%B1%CA%B3%A9" target="_blank"/>
<menu name="周筆暢" url="http://post.baidu.com/f?kw=%D6%DC%B1%CA%B3%A9" target="_blank"/>
</menu>
<menu name="香港" url="">
<menu name="成龍" url="http://post.baidu.com/f?kw=%B3%C9%C1%FA" target="_blank"/>
</menu>
</menu>
<menu name="日韓明星" url="Admin_Dep.aspx">
<menu name="金喜善" url="http://post.baidu.com/f?kw=%BD%F0%CF%B2%C9%C6" target="_blank"/>
<menu name="金喜善" url="http://post.baidu.com/f?kw=%BD%F0%CF%B2%C9%C6" target="_blank"/>
</menu>
<menu name="歐美明星" url="#"/>
</menu>
<menu name="娛樂">
<menu name="快樂男聲" url="#" target="_blank">
<menu name="陳楚生" url="http://post.baidu.com/f?kw=%B3%C2%B3%FE%C9%FA" target="_blank"/>
<menu name="蘇醒" url="http://post.baidu.com/f?kw=%CB%D5%D0%D1"/>
</menu>
</menu>
<menu name="體育">
<menu name="體育俱樂部" url="#"/>
</menu>
<menu name="軍事">
<menu name="戰鬥機" url="#"/>
</menu>
</menu>
儲存檔案名稱為menu.xml
在HTML中,Javascript代碼如下:
//建立XMLdom對象,並載入xml,xmlFilePath為xml的文本路徑
function CreateXMLDoc(xmlFilePath)
{
if(window.ActiveXObject)
{
//獲得操作的xml檔案的對象
var msXMLdom = new ActiveXObject('Microsoft.XMLDOM');
msXMLdom.async = false;
msXMLdom.load(xmlFilePath);
return msXMLdom;
}
else
{
var oXmlHttp = new XMLHttpRequest() ;
oXmlHttp.open( "GET", xmlFilePath, false ) ;
oXmlHttp.send(null) ;
return oXmlHttp.responseXML;
}
}
//建立對象
var xmlDoc;
xmlDoc=CreateXMLDoc("menu.xml");
var rootNode=xmlDoc.lastChild;
然後寫一個產生樹的函數:
//返回樹形結構的HTML代碼,參數node為節點名,level為當前節點相對於根節點的深度值
function BuilderTree(nodeName,level)
{
//子功能表項,縮排的像素數
var indent=10;
var temp="";
level=level==null ? 0 : level;
var nodes=nodeName.childNodes;
for(var i=0;i<nodes.length;i++)
{
//當該節點沒下級節點時
if(nodes[i].childNodes.length<1)
{
//當前菜單的名稱
temp+="<div style='margin-left:"+level*indent+"px;cursor:hand;''>";
temp+="<b>-</b> ";
//是否開啟新視窗
var target=nodes[i].getAttribute("target")==null ? "" : "target='"+nodes[i].getAttribute("target")+"'";
temp+="<a href='"+nodes[i].getAttribute("url")+"' "+target+">"+nodes[i].getAttribute("name")+"</a>";
temp+="</div>";
continue;
}
//當前菜單的名稱
temp+="<div style='margin-left:"+level*indent+"px;cursor:hand;' onclick='show(this)'>";
temp+="<b>+</b> <b>"+nodes[i].getAttribute("name")+"</b>";
temp+="</div>";
//當前菜單的下級內容
temp+="<div style='margin-left:"+indent+"px;cursor:hand;display:none'>";
temp+=BuilderTree(nodes[i],level+1);
temp+="</div>";
}
return temp;
}
在上面的代碼中,用到了遞迴來實現遍曆XML中的所有資料;
然後,為了實現滑鼠事件,再寫一個方法;
show函數如下:
//操作某個節點的下一節點nextSibling是否顯示;
function show(obj)
{
//當前節點的下一節點
var nextNode=obj.nextSibling;
//當前節點的頭部符號節點,就是功能表項目前面+、-號
var subNode=obj.firstChild.firstChild;
if(nextNode.nodeType==1)
{
with(eval(nextNode))
{
if(style.display=="")
{
style.display="none";
subNode.nodeValue="+";
}else
{
style.display="";
subNode.nodeValue="-";
}
}
}
}
因為每個菜單所屬的子級內容與它自身並不在一個div中,這裡僅傳了this就是自身,為了操作它僅隨後面的一個div,用到了nextSibling方法;並用 var subNode=obj.firstChild.firstChild;找到每個菜單頭部的加減號用於展開或拆疊時顯示;
看完上面這些,最終是要輸出的,在HTML頁面的body中,寫入:
<div id="TreeMenu"></div>
然後head中,寫入
<script type="text/javascript" language="javascript" defer="defer">
//將處理過的XML資料,插入到頁面的相應位置
var d=document.getElementById("TreeMenu");
d.innerHTML=BuilderTree(rootNode);
</script>
這樣就OK了。
代碼中我寫了一些注釋,應該不難看懂,我就不再做過多的解釋了。
源檔案:
http://files.cnblogs.com/2hill/TreeMenu.rar
附一個《javascript操作xml產生下拉式功能表》
http://hi.baidu.com/2hill/blog/item/1c234a952fb53f0c7bf4809c.html