js中的计时器

在JS中做二级菜单时,被一个鼠标移出时隐藏的小问题困扰了很久.

<script>
function Menu(id){
    var _this=this;
    this.obj=document.getElementById(id);
    this.trigger=getFirstChild(this.obj);
    this.menuOne=getLastChild(this.obj);
    this.menuOneLi=getChildren(this.menuOne);
    this.menuOneLiA=[];
    this.menuTwo=[];

    for(var i=0;i<this.menuOneLi.length;i++){
        this.menuOneLiA.push(getFirstChild(this.menuOneLi[i]));
        this.menuTwo.push(getLastChild(this.menuOneLi[i]));
    }
    //隐藏一级菜单
    this.menuOne.style.display='none';
    //隐藏二级菜单
    for(var i=0;i<this.menuTwo.length;i++){
        this.menuTwo[i].style.display='none';    
    }
    //为每一个一级菜单的li添加事件
    for(var i=0;i<this.menuOneLiA.length;i++){
        
        this.menuOneLiA[i].onmouseover=function(){
            //清除计时器
            clearTimeout(_this.timer);
            //隐藏所有的二级菜单
            for(var j=0;j<_this.menuTwo.length;j++){
                _this.menuTwo[j].style.display='none';    
            }
            //显示此li对应的二级菜单
            getNextElement(this).style.display='block';    
        }
    }
    //一级菜单的鼠标移出事件
    this.menuOne.onmouseout=function(){
        _this.menuOneClear();
    }
    this.trigger.onmouseover=function(){
        _this.showMenuOne();
    }
    
}
Menu.prototype.showMenuOne=function(){
    clearTimeout(this.timer);
    this.menuOne.style.height='auto';
    this.menuOne.style.display='block';    
    
}
Menu.prototype.menuOneClear=function(){
        var _this=this;
    //关键在于这一句,在开启一个计时器的时候,要清除掉已经开启的上一个计时器,因为计时器是会叠加的
    //如果没有在清掉原有计时器的情况下,开启新的计时器,会导致菜单无论如何都会消失. clearTimeout(
this.timer); this.timer=setTimeout(function(){ _this.menuOne.style.display='none'; },500); } window.onload=function(){ new Menu('header_menu'); }

HTML我就不贴了,主要是看JS的逻辑.
算了,还是贴一下吧!

<div class="header_nav_mid_handler" id="header_menu">
            <a href="#" class="header_nav_mid_handler_all" id="header_btn">全部商品分类</a>
            <!--隐藏的一级菜单-->
            <ul class="header_nav_mid_menu">
                <li class="header_nav_mid_menu_li bedroom">
                    <a href="#" class="header_nav_mid_menu_a">卧室</a>
                    <ul class="header_nav_mid_list">
                        <li><a href="#">二级菜单</a></li>
                        <li><a href="#">二级菜单</a></li>
                        <li><a href="#">二级菜单</a></li>
                        <li><a href="#">二级菜单</a></li>
                        <li><a href="#">二级菜单</a></li>
                        <li><a href="#">二级菜单</a></li>
                    </ul>
                </li>
            </ul>
</div>

 在上面的JS中我是用的是自己封装的一些获取元素的方法,也贴上来共同讨论

//在IE6下,不支持getElementsByClassName()方法,此方法可以进行兼容处理
function hasClass(node,className){
        var class_names=node.className.split(/s+/);
        for(var i=0;i<class_names.length;i++){
            if(class_names[i]==className){
                return true;    
            }
        }
        return false;
}

function getByClassName(className){
    if(document.getElementsByClassName){
        return document.getElementsByClassName(className);    
    }
    var nodes=document.getElementsByTagName('*');
    var arr=[];
    for(var i=0;i<nodes.length;i++){
        if(hasClass(nodes[i],className)){
            arr.push(nodes[i]);
        }
    }
    return arr;
}
//获取第一个子元素的兼容方法 OK
function getFirstChild(obj){
    if(obj.firstElementChild){
        return obj.firstElementChild;    
    }else{
        return obj.firstChild;    
    }
}
//获取最后一个子元素的兼容方法 OK
function getLastChild(obj){ 
    if(obj.lastElementChild){
        return obj.lastElementChild;    
    }else{
        return obj.lastChild;
    }
}
//获取preiousSibling的兼容方法 OK
function getPrevElement(obj){
    if(obj.previousElementSibling){
        return obj.previousElementSibling;    
    }else{
        return obj.previousSibling;
    }
}
//获取nextSibling的兼容方法 OK
function getNextElement(obj){
    if(obj.nextElementSibling){
        return obj.nextElementSibling;    
    }else{
        return obj.nextSibling;
    }
}
//获取子元素的方法 OK
function getChildren(obj){
    var nodes=obj.childNodes;
    var arr=[];
    for(var i=0;i<nodes.length;i++){
        if(nodes[i].nodeType==1){
            arr.push(nodes[i]);    
        }
    }
    return arr;
    
}
// ajax的get方法
function Ajax(url,fnSuccess,fnFailed){
    var xhr=null;
    if(window.XMLHttpRequest){
        xhr=new XMLHttpRequest();    
    }else{
        xhr=new ActiveXObject('Microsoft.XMLHTTP');    
    }
    xhr.open('GET',url,true);
    xhr.send();
    xhr.onreadystatechange=function(){
        if(xhr.readyState==4){
            if(xhr.status==200){
                fnSuccess(xhr.responseText);    
            }else{
                if(fnFailed){
                    fnFailed();    
                }    
            }
        }
    }
}
原文地址:https://www.cnblogs.com/zhangfengyang/p/4643591.html