收藏本站腾讯微博新浪微博

经典论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

蓝色理想 最新研发动态 网站开通淘帖功能 - 蓝色理想插件 论坛内容导读一页看论坛 - 给官方提建议

论坛活动及任务 地图和邮件任务 请多用悬赏提问 热夏来袭,选一款蓝色理想的个性T恤吧!

手机上论坛,使用APP获得更好体验 急需前端攻城狮,获得内部推荐机会 论坛开通淘帖功能,收藏终于可以分类了!

搜索
查看: 3955|回复: 10

发布一个JS解析XML生成无限导航

[复制链接]
发表于 2009-9-19 12:03:14 | 显示全部楼层 |阅读模式
源码在附件
  1. // JavaScript Document
  2. /*
  3. 这段时间因为要做导航弹出菜单,于是便上网找了下现成的代码,然而一个个一大堆的CSS还有UL LI看
  4. 得我头晕眼花,于是还是决定自己写个,因为XML可以很好的描述一个有序的对象,于是便选用了JS解析XML来生成,
  5. 经过数个下班后的晚上,效果终于出来了,能达到的效果不比网上的差,
  6. 可以无限扩展你的节点,并且也在IE6和FF3.5.6下通过
  7. 测试。欢迎加QQ:279074838一起学习讨论。
  8. */
  9. XmlNav=function()
  10. {
  11.         //----------------------------------------------一些默认的属性值和常量-start
  12.         var nodeLevel=0;//节点级别,默认为0       
  13.         var navCssText_ul="cursor:pointer;width:100;height:20;";
  14.         var navCssText_li="background-color:#ccc;border:1px solid #999;";
  15.         var bgColorWhenOver="#FFFFFF";
  16.         var bgColorWhenOut="#CCCCCC";
  17.         var target="_blank";
  18.         var navCssBasic_ul="padding:0;margin:0;position:absolute;z-index:9999;visibility:visible;list-style-type:none";
  19.         var navCssBasic_li="position:relative;z-index:9999;padding:-1 0 0 0;margin:-1 0 0 0;";
  20.         this.LAYOUT_UP="UP";//导航弹出的方向,给对象调用
  21.         this.LAYOUT_DOWN="DOWN";//导航弹出的方向,给对象调用
  22.         this.LAYOUT_LEFT="LEFT";//导航弹出的方向,给对象调用
  23.         this.LAYOUT_RIGHT="RIGHT";        //导航弹出的方向,给对象调用
  24.         //----------------------------------------------一些默认的属性值和常量-stop
  25.         //----------------------------------------------变量合集-start
  26.         this.el;//页面显示的控件
  27.         this.xmlUrl;//XML的路径       
  28.         this.ulCssText;//整个导航以UL和LI来组成,所以可以自定义它们的CSS属性
  29.         this.liCssText;//整个导航以UL和LI来组成,所以可以自定义它们的CSS属性
  30.         this.layout;//当前导航弹出的方向
  31.         this.colorWhenOver;//当鼠标移悬浮在导航时的背景颜色
  32.         this.colorWhenOut;//当鼠标移开时的背景颜色
  33.         this.hrefTarget;//每个导航连接的打开的目标
  34.        
  35.         var mylayout;//NAV私有变量,接收this.layout的值
  36.         var firstNodeLenth;//XML文档内一级节点的长度,也即是根节点的子节点长度
  37.         //----------------------------------------------变量合集-stop
  38.        
  39.         this.create=function()
  40.         {
  41.                 /*各种属性的初始化*/
  42.                 this.el=typeof(this.el)=="object"?this.el:document.getElementById(this.el);//假如传进来的不是一个有效的对象,那么是一个对象的ID
  43.                 mylayout=!this.layout?this.LAYOUT_DOWN:this.layout;               
  44.                 navCssText_ul=!this.ulCssText?navCssText_ul:this.ulCssText;
  45.                 navCssText_li=!this.liCssText?navCssText_li:this.liCssText;
  46.                 navCssText_ul+=navCssBasic_ul;
  47.                 navCssText_li+=navCssBasic_li;
  48.                
  49.                 bgColorWhenOver=!this.colorWhenOver?bgColorWhenOver:this.colorWhenOver;
  50.             bgColorWhenOut=!this.colorWhenOut?bgColorWhenOut:this.colorWhenOut;
  51.                 target=!this.hrefTarget?target:this.hrefTarget;
  52.                
  53.                 var xmlDom=getXml(this.xmlUrl);                               
  54.                 if(xmlDom)
  55.                 {
  56.                                 var nodes=xmlDom.documentElement;
  57.                                     nodes=cleanWhitespace(nodes);
  58.                                         firstNodeLenth=nodes.childNodes.length;                                       
  59.                                         createNode(this.el,nodes,nodeLevel);                               
  60.                 }               
  61.         }
  62.         /*判断浏览器函数(从网上找的),假如所有浏览器都按标准办事,那么就没有这个函数存在的必要了*/
  63.         var getBrowser=function()
  64.         {
  65.                         var Sys = {};
  66.                         var ua = navigator.userAgent.toLowerCase();
  67.                         var re =/(msie|firefox|chrome|opera|version).*?([\d.]+)/;
  68.                         var m = ua.match(re);
  69.                         Sys.browser = m[1].replace(/version/, "'safari");
  70.                         Sys.ver = m[2];
  71.                         return Sys;
  72.         }
  73.         var sys = getBrowser();
  74.         /*XML空白缩进处理,由于IE与非IE浏览器对XML空白缩进的处理不一样那么将统一使用本函数做清除空白缩进处理*/
  75.         var cleanWhitespace = function(node)
  76.         {               
  77.                   var notWhitespace = /\S/;
  78.                   for (var i=0; i < node.childNodes.length; i++)
  79.                   {
  80.                           var childNode = node.childNodes[i];
  81.                           if ((childNode.nodeType == 3)&&(!notWhitespace.test( childNode.nodeValue)))
  82.                           {
  83.                                   node.removeChild(node.childNodes[i]);
  84.                                   i--;
  85.                           }
  86.                           if (childNode.nodeType == 1)
  87.                           {            
  88.                                   cleanWhitespace(childNode);
  89.                           }
  90.                   }
  91.                   return node;
  92.          }
  93.         /*加载XML的函数,将返回一个DOM*/
  94.         var getXml=function(xmlUrl)
  95.         {
  96.                 var xmlDoc;               
  97.                 xmlDoc=sys.browser=="msie"?new ActiveXObject("Microsoft.XMLDOM"):document.implementation.createDocument("","",null);//判断XML的加载方式       
  98.                 xmlDoc.async=false;               
  99.                 xmlDoc.load(xmlUrl);
  100.                 return(xmlDoc);
  101.         }
  102.        
  103.         /*主函数,遍历每个XML节点而创建导航每个节点,递归遍历,从而实现无限导航无限扩展,也可以根据这个思想来转变为一颗XML树*/
  104.         var createNode=function(parentNode,nodes,nodeLevel)
  105.         {               
  106.                         var ul=document.createElement("ul");
  107.                         var x=parentNode.getBoundingClientRect().left;//节点的左上角的X轴值
  108.                         var y=parentNode.getBoundingClientRect().top;//节点的左上角的Y轴值                       
  109.                         var borderWidth=parentNode.style.borderWidth;
  110.                         var w=parentNode.style.width;
  111.                         var h=parentNode.style.height;                       
  112.                         borderWidth=borderWidth!=""?parseInt(borderWidth.substring(0,1)):1;        //获取边框的单位是四条边的值,所以我只要第一个只可
  113.                         w=w!=""?parseInt(w.replace("px","")):100;//获取的宽度带单位所以要清除PX
  114.                         h=h!=""?parseInt(h.replace("px","")):25;
  115.                         ul.style.cssText=navCssText_ul;                       
  116.                         ul.style.visibility=nodeLevel==0?"visible":"hidden";//假如为根节点,那么节点显示,否则隐藏                       
  117.                        
  118.                         //------------------------------------------------设置导航弹出的方向---开始
  119.                         if(nodeLevel==0)
  120.                         {
  121.                                 ul.style.left=x-borderWidth*2;
  122.                                 ul.style.top=y-borderWidth*2;
  123.                         }
  124.                         else if(nodeLevel==1)
  125.                         {                               
  126.                                 if(mylayout=="UP")
  127.                                 {
  128.                                         ul.style.top=y-h*firstNodeLenth-firstNodeLenth;
  129.                                         ul.style.left=x-borderWidth;
  130.                                 }
  131.                                 else if(mylayout=="DOWN")
  132.                                 {
  133.                                         ul.style.top=y+h;
  134.                                         ul.style.left=x-borderWidth;
  135.                                 }
  136.                                 else if(mylayout=="LEFT")
  137.                                 {
  138.                                         ul.style.top=h/5;
  139.                                         ul.style.left=sys.browser=="msie"?x-w:x-w-borderWidth*2;
  140.                                 }
  141.                                 else if(mylayout=="RIGHT")
  142.                                 {
  143.                                         ul.style.top=h/5;
  144.                                         ul.style.left=sys.browser=="msie"?x+w-borderWidth*2:x+w;
  145.                                 }
  146.                                 else
  147.                                 {
  148.                                         ul.style.top=y+h;
  149.                                         ul.style.left=x-borderWidth;
  150.                                 }                                       
  151.                         }
  152.                         else
  153.                         {
  154.                                 if(mylayout=="LEFT")
  155.                                 {                                       
  156.                                         ul.style.left=sys.browser=="msie"?0-w:0-w-borderWidth*2;
  157.                                         ul.style.top=h/5;
  158.                                 }                                       
  159.                                 else
  160.                                 {
  161.                                         ul.style.left=sys.browser=="msie"?w-borderWidth*2:w;
  162.                                         ul.style.top=h/5;
  163.                                 }
  164.                         }
  165.                         //------------------------------------------------设置导航弹出的方向---结束
  166.                         if(nodeLevel==0)//创建导航的根节点,之所以不写在FOR循环里,那是因为加入XML节点过多,那么每次递归都判断一次,将会浪费资源
  167.                         {                       
  168.                                         var nodeNameValue=nodes.getAttribute("name")!=null?nodes.getAttribute("name"):nodes.nodeName;                       
  169.                                         var nodeUrlValue=nodes.getAttribute("href")!=null?nodes.getAttribute("href"):"#";                                       
  170.                                         var li=document.createElement("li");
  171.                                         var links=document.createElement("a");
  172.                                         var nodeName=document.createTextNode(nodeNameValue);
  173.                                         links.setAttribute("href",nodeUrlValue);
  174.                                         links.setAttribute("target",target);                                       
  175.                                         links.appendChild(nodeName);                                       
  176.                                         li.style.cssText=navCssText_li;
  177.                                         li.style.width=w;
  178.                                         li.style.height=h;
  179.                                         li.style.lineHeight=h+"px";
  180.                                         li.appendChild(links);                       
  181.                                         ul.appendChild(li);                                       
  182.                                         createNode(li,nodes.childNodes,nodeLevel+1);                                       
  183.                         }
  184.                         else//子节点的遍历开始,并创建导航的德弹出节点
  185.                         {               
  186.                                 var nlen=nodes.length;               
  187.                                 for(var i=0;i<nlen;i++)
  188.                                 {       
  189.                                         var xmlNode=nodes[i];
  190.                                         xmlNode=cleanWhitespace(xmlNode);
  191.                                         var nodeNameValue=xmlNode.getAttribute("name")!=null?xmlNode.getAttribute("name"):xmlNode.nodeName;
  192.                                         var nodeUrlValue=xmlNode.getAttribute("href")!=null?xmlNode.getAttribute("href"):"";               
  193.                                         var li=document.createElement("li");
  194.                                         var links=document.createElement("a");
  195.                                         var nodeName=document.createTextNode(nodeNameValue);
  196.                                         links.setAttribute("href",nodeUrlValue);
  197.                                         links.setAttribute("target",target);
  198.                                         links.appendChild(nodeName);
  199.                                         li.style.cssText=navCssText_li;
  200.                                         li.style.width=w;
  201.                                         li.style.height=h;
  202.                                         li.style.lineHeight=h+"px";
  203.                                         li.appendChild(links);                       
  204.                                         ul.appendChild(li);
  205.                                        
  206.                                         li.onmouseover=function()
  207.                                         {
  208.                                                 this.style.backgroundColor=bgColorWhenOver;
  209.                                         }
  210.                                         li.onmouseout=function()
  211.                                         {
  212.                                                 this.style.backgroundColor=bgColorWhenOut;
  213.                                         }                                       
  214.                                         parentNode.onmouseover=function()
  215.                                         {       
  216.                                                         this.style.backgroundColor=bgColorWhenOver;
  217.                                                         this.hasChildNodes&&this.childNodes.length>1?this.childNodes[1].style.visibility="visible":false;//当每个导航存在下级导航时那么显示它的子导航                                       
  218.                                         }
  219.                                         function nodeWhenOut(evt)
  220.                                         {
  221.                                                 try
  222.                                                 {
  223.                                                                 evt==null?evt=window.event:evt;//因为IE和FF的EVENT获取不一样,所以需要判断                                     
  224.                                                                 if (evt.currentTarget&&evt.relatedTarget != this&&this != evt.relatedTarget.parentNode)
  225.                                                                 {
  226.                                                                    this.hasChildNodes&&this.childNodes.length>1?this.childNodes[1].style.visibility="hidden":false;                                                          
  227.                                                                 }
  228.                                                                 else if(this.contains(event.toElement ) == false)
  229.                                                                 {
  230.                                                                         this.hasChildNodes&&this.childNodes.length>1?this.childNodes[1].style.visibility="hidden":false;
  231.                                                                 }                                                                 
  232.                                                                 this.style.backgroundColor=bgColorWhenOut;
  233.                                                
  234.                                                 }catch(e){}/*因为EVENT在FF下或提示一个错误,虽然无关紧要但总不好看,所以catch不做任何处理*/
  235.                                         }
  236.                                         parentNode.onmouseout=nodeWhenOut;       
  237.                                         xmlNode.hasChildNodes&&xmlNode.childNodes.length>0?createNode(li,xmlNode.childNodes,nodeLevel+1):false;        //鼠标离开,自导航隐藏
  238.                                 }
  239.                         }
  240.                                 parentNode.appendChild(ul);//使导航添加到页面
  241.                 }
  242. }
复制代码

以上代码保存为一个JS文件,使用时调用就好了

  1. <script language="javascript"  src="xmlNav.js" charset="utf-8"></script>
  2. <style type="text/css">
  3. body{margin:0px; background-color:#000}
  4. a{width:100%; height:100%;}
  5. a:link{text-decoration:none; color:#000}
  6. a:visited{text-decoration:none;color:#000}
  7. a:hover{text-decoration:none;color:#000}
  8. a:active{text-decoration:none;color:#000}
  9. </style>
  10. <body>
  11. <table width="100%" height="100%"><tr><td><center>
  12. <table  border="0" style="text-align:center;" cellpadding="0" cellspacing="0">     
  13.     <tr>
  14.             <td rowspan="3"><div class="navl" id="navl2" style="width:100; height:20"></div> </td>
  15.         <td><div class="navl" id="navl0" style="width:100; height:20"></div> </td>
  16.         <td rowspan="3"> <div class="navl" id="navl3" style="width:100; height:20"></div></td>
  17.     </tr>
  18.     <tr>
  19.             <td ><div class="navl" id="navl1" style="width:100; height:20; margin-top:10px;"></div></td>        
  20.     </tr>
  21.     <tr>
  22.             <td ><div class="navl" id="default" style="width:100; height:20; margin-top:10px;"></div></td>        
  23.     </tr>
  24. </table>
  25. </center></td></tr></table>
  26. </div>

  27. <script language="javascript">

  28.         var css_ul="cursor:pointer;width:100;height:20;font-size:12px;";
  29.         var css_li="background-color:#02fee9;border:1px solid #000;";

  30.        
  31.                 var xmlNav=new XmlNav();
  32.                 xmlNav.el="navl0";
  33.                 xmlNav.xmlUrl="xmlNav0.xml";
  34.                 xmlNav.layout=xmlNav.LAYOUT_UP;       
  35.                 xmlNav.ulCssText=css_ul;
  36.                 xmlNav.liCssText=css_li;
  37.                 xmlNav.colorWhenOver="#e4f9f7";
  38.                 xmlNav.colorWhenOut="#02fee9";
  39.                 xmlNav.hrefTarget="_blank"
  40.                 xmlNav.create();
  41.                
  42.                 var xmlNav=new XmlNav();
  43.                 xmlNav.el="navl1";
  44.                 xmlNav.xmlUrl="xmlNav1.xml";
  45.                 xmlNav.layout=xmlNav.LAYOUT_DOWN;       
  46.                 xmlNav.ulCssText=css_ul;
  47.                 xmlNav.liCssText=css_li;
  48.                 xmlNav.colorWhenOver="#e4f9f7";
  49.                 xmlNav.colorWhenOut="#02fee9";
  50.                 xmlNav.create();
  51.                
  52.                 var xmlNav=new XmlNav();
  53.                 xmlNav.el="navl2";
  54.                 xmlNav.xmlUrl="xmlNav2.xml";
  55.                 xmlNav.layout=xmlNav.LAYOUT_LEFT;       
  56.                 xmlNav.ulCssText=css_ul;
  57.                 xmlNav.liCssText=css_li;
  58.                 xmlNav.colorWhenOver="#e4f9f7";
  59.                 xmlNav.colorWhenOut="#02fee9";
  60.                 xmlNav.create();
  61.                
  62.                
  63.                 var xmlNav=new XmlNav();
  64.                 xmlNav.el="navl3";
  65.                 xmlNav.xmlUrl="xmlNav3.xml";
  66.                 xmlNav.layout=xmlNav.LAYOUT_RIGHT;       
  67.                 xmlNav.ulCssText=css_ul;
  68.                 xmlNav.liCssText=css_li;
  69.                 xmlNav.colorWhenOver="#e4f9f7";
  70.                 xmlNav.colorWhenOut="#02fee9";
  71.                 xmlNav.create();
  72.                
  73.                 var xmlNav=new XmlNav();
  74.                 xmlNav.el="default";
  75.                 xmlNav.xmlUrl="xmlNav0.xml";
  76.                 xmlNav.create();
  77. </script>
复制代码

[[i] 本帖最后由 llpoo 于 2009-9-19 13:15 编辑 ]

xmlNav.rar

4.97 KB, 下载次数: 344

源码

发表于 2009-9-19 12:23:23 | 显示全部楼层
支持一下。

不过,将xml改成json格式更方便哦~~当成js文件引用就好了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-19 12:47:04 | 显示全部楼层
我比较偏爱XML
回复 支持 反对

使用道具 举报

发表于 2009-9-19 13:28:21 | 显示全部楼层
虽然不懂.不过先顶了.下载了再说..
回复 支持 反对

使用道具 举报

发表于 2009-9-19 13:34:10 | 显示全部楼层
google chrome下没反应。
回复 支持 反对

使用道具 举报

发表于 2009-9-19 13:36:21 | 显示全部楼层

回复 5# yamanyin 的帖子

这也是我推荐json的原因。。。相对来说json比较不需要考虑兼容性的问题
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-19 14:51:38 | 显示全部楼层

回复 6# Sheneyan 的帖子

嗯,这是个问题。找个时间再改写一下,可以支持JSON
回复 支持 反对

使用道具 举报

发表于 2009-9-20 05:06:31 | 显示全部楼层
原帖由 [i]llpoo 于 2009-9-19 14:51 发表
嗯,这是个问题。找个时间再改写一下,可以支持JSON


而且不需要处理那些空白。
回复 支持 反对

使用道具 举报

发表于 2009-9-20 08:05:34 | 显示全部楼层
顶一下下载学习..
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-20 14:57:08 | 显示全部楼层

回复 8# icedblog 的帖子

这里有一个问题,JSON不知道各大语言是否有支持的API?比如有桌面应用也需要同样结构的目录,那是否还得自己写函数解析JSON?
回复 支持 反对

使用道具 举报

发表于 2016-12-2 14:53:12 | 显示全部楼层
我来了,我来下载东西了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|小黑屋|Archiver|手机版|blueidea.com ( ICP05002321 )  

GMT+8, 2019-10-21 11:13 , Processed in 0.109100 second(s), 10 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表