javascript编写web组件:多级菜单

本文介绍了一种使用纯JavaScript实现的自定义多级菜单方案,通过递归创建DOM节点来构建多级菜单结构,并利用事件监听实现了菜单的展开与收起功能。

    在web上编写菜单一直是比较头疼的事情,要是有个类直接套用就好了,最近又要做网站了,烦人,要求做的还是多级菜单,唉,废话少说,遇到问题就要解决啊,看代码:

   function is(e, handler) {  
    if (e.type != 'mouseout' && e.type != 'mouseover') return false;  
   var reltg = e.relatedTarget ? e.relatedTarget : e.type == 'mouseout' ? e.toElement : e.fromElement;  
    while (reltg && reltg != handler)  
        reltg = reltg.parentNode;  
    return (reltg != handler);  
}
   var menu=function(obj){
    var div=document.createElement("div");
    div.style.position="absolute";
    div.style.left="-1000px";
    div.style.top="0px";
    div.flag="menu"
    document.body.appendChild(div);
    div.onmouseout=function(e){
     
     var e=e||window.event;
     if(!is(e,this)) return;
        e=e.relatedTarget?e.relatedTarget:e.toElement;
        if(e.flag!="menu"){
         div.style.left="-1000px";
       div.style.top="0px"
        }
    }
    function exec(obj,div){
     var a;
     for(a in obj){
      var item=document.createElement("div");
       item.flag="menu";
      item.style.textAlign="center";
      item.innerHTML=typeof(obj[a])=="object"?a:'<a flag="menu" href="'+obj[a]+'">'+a+'</a>';
      div.appendChild(item);
      if(typeof(obj[a])=="object"){
       var idiv=document.createElement("div");
       idiv.style.position="absolute"
       idiv.flag="menu";
       idiv.style.left="-1000px";
       idiv.style.top="0px";
       item.onmouseover=function(e){
        var e=e||window.event;
        if(!is(e,this)) return;
        e=e.relatedTarget?e.relatedTarget:e.fromElement;
        if (e != idiv) {
         //alert(this.parentNode.offsetTop + this.offsetTop);
         idiv.style.left = this.parentNode.offsetLeft + this.offsetWidth - 1 + "px";
         idiv.style.top = this.parentNode.offsetTop + this.offsetTop + "px";
        }
        if(e.stopPropagation){
         e.stopPropagation();
        }else{
         window.event.cancelable=true;
        }
       }
       item.onmouseout=function(e){
       var e=e||window.event;
       if(!is(e,this)) return;
        e=e.relatedTarget?e.relatedTarget:e.toElement;
        
        if (!(e ==idiv || e.parentNode== idiv || e.parentNode.parentNode==idiv)) {
         
         idiv.style.left = "-1000px";
         idiv.style.top = "0px";
        }
        
       }
       idiv.onmouseout=function(e){
        var e=e||window.event;
        if(!is(e,this)) return;
        e=e.relatedTarget?e.relatedTarget:e.toElement;
        if(e.flag!="menu"){
        
         var a=document.getElementsByTagName("*");
         for(var i=0;i<a.length;i++){
          if(a[i].tagName=="DIV" && a[i].flag=="menu"){
          a[i].style.left="-1000px";
       a[i].style.top="0px" 
          }
          
         }
         
        }
        if(e.stopPropagation){
         e.stopPropagation();
        }else{
         window.event.cancelable=true;
        }
        
       }
       document.body.appendChild(idiv);
       exec(obj[a],idiv);
      }
     }
     
         }
     exec(obj,div);
    this.bind=function(ee,flag){
     if(flag=="v"){
      ee.onmouseover=function(e){
       var e=e||window.event;
       var e1=e.relatedTarget?e.relatedTarget:e.fromElement;    ;
        if (e1 != div) {
         div.style.top = ee.getBoundingClientRect().top + ee.offsetHeight-2 + "px";
         div.style.left = ee.getBoundingClientRect().left + "px";
        }
       //alert(div.innerHTML);
      }
      ee.onmouseout=function(e){
       //alert(e);
       var e=e||window.event;
       var e1=e.relatedTarget?e.relatedTarget:e.toElement;
       //alert(e.toElement);
        if (e1.flag!="menu") {
         div.style.left = "-1000px";
         div.style.top = "0px";
        }
      }
     }
    }
    
    
   }

这个的is函数是为了解决ie和ff下的onmouseover和onmouseout问题,保证可以模拟出onmouseenter和onmouseleave的效果,menu留出一个bind方法,用来绑定元素的,下面看示例:

var s=new menu({"adsfsdf":"http://www.baidu.com",
   "sasdasd":{"asdasdasd":34,
   "eret":3434,
   "treter":{"wedqw":4353,
   "werew":3453}}
   });
   s.bind(document.getElementById("w"),"v");

这里用了json数据格式来进行数据传递,比如adsfsdf就是菜单名称,http://www.baidu.com就是链接地址,或者后面跟一个json就是表示下一级菜单,还算比较方便的吧。

      当然我这里在ff下实现还有些问题,如有哪有高手看出代码弊端的话,还望指点下小弟。

      本人水平有限,代码不妥之处,还望多多指点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值