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();
                }
            }
        }
    }
}
时间: 2024-08-26 08:10:08

js中的计时器的相关文章

JS中的计时器事件

JS可以实现很多java代码不易完成的功能.这里学习一些js中的计时器事件. JavaScript 一个设定的时间间隔之后来执行代码,称之为计时事件. 主要通过两个方法来实现: 1.setInterval() - 间隔指定的毫秒数不停地执行指定的代码. 2.setTimeout() - 暂停指定的毫秒数后执行指定的代码 并且,这两个方法都是window对象的方法. 首先,介绍setInterval()方法,该方法值得是间隔一定的毫秒数不停的执行指定的代码. 语法:window.setInterv

js中的计时器事件`setTimeout()` 和 `setInterval()`

js中的计时器事件 在js中,通常会有一些事件,我们需要让它 间隔一段时间之后再发生,或者 每隔一段时间 发生一次,那就需要用到我们js中的计时事件 计时事件主要有两种: setTimeout() ---- 间隔一定的时间之后执行 setInterval() ----每间隔一定的时间执行一次(重复性执行) setTimeout() 间隔一定的时间之后`执行指定的语句或函数. 例如:3s后跳转到前一个页面. <script type="text/javascript"> se

在Node.js中实现任务调度与执行

在Node.js中实现任务调度与执行 作者:chszs,未经博主允许不得转载.经许可的转载需注明作者和博客主页:http://blog.csdn.net/chszs 批处理是业务开发中经常会遇到的需求,比如银行对账单的处理,又比如广告邮件的推送. Node.js在批处理方面也有一些优秀的库,node-schedule就是其中之一. node-schedule是一个轻量级的.基于Node.js的.类似于cron的调度器工具.其介绍可查看: https://www.npmjs.com/package

原生 JS 中对象相关 API 合集

https://juejin.im/entry/58f8a705a0bb9f0065a4cb20 原文链接:https://microzz.com/2017/04/20/jsobject/ 原生 JavaScript 中对象相关 API 合集 - 对象篇.现在 jQuery 已经没有那么有优势了,原生 JS 赶紧学起来... -- 由microzz分享 Microzz [email protected] 主页 文章 标签 GitHub 关于我 掘金专栏 SegmentFault Vue音乐播放器

js中获取时间new date()的用法

js中获取时间new date()的用法 获取时间:   var myDate = new Date();//获取系统当前时间 获取特定格式的时间: 1 myDate.getYear(); //获取当前年份(2位) 2 myDate.getFullYear(); //获取完整的年份(4位,1970-????) 3 myDate.getMonth(); //获取当前月份(0-11,0代表1月) 4 myDate.getDate(); //获取当前日(1-31) 5 myDate.getDay();

JS中的运算符&amp;JS中的分支结构

一.JS中的运算符 1.算术运算(单目运算符) + 加.- 减.* 乘./ 除.% 取余.++ 自增.-- 自减 >>> +:有两种作用,连接字符串/加法运算.当+两边全为数字时,进行加法运算: 当+两边有任意一边为字符串时,起连接字符串的作用,连接之后的结果为字符串 除+外,其余符号运算时,会先尝试将左右变量用Number函数转为数字 >>> /: 结果会保留小数点 >>> ++: 自增运算符,将变量在原有基础上+1: --: 自减运算符,将变量在原

Js中的数据属性和访问器属性

Js中的数据属性和访问器属性 在javaScript中,对象的属性分为两种类型:数据属性和访问器属性. 一.数据属性 1.数据属性:它包含的是一个数据值的位置,在这可以对数据值进行读写. 2.数据属性包含四个特性,分别是: configurable:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或能否把属性修改为访问器属性,默认为true enumerable:表示能否通过for-in循环返回属性 writable:表示能否修改属性的值 value:包含该属性的数据值.默

在Node.js中使用RabbitMQ系列二 任务队列

在上一篇文章在Node.js中使用RabbitMQ系列一 Hello world我有使用一个任务队列,不过当时的场景是将消息发送给一个消费者,本篇文章我将讨论有多个消费者的场景. 其实,任务队列最核心解决的问题是避免立即处理那些耗时的任务,也就是避免请求-响应的这种同步模式.取而代之的是我们通过调度算法,让这些耗时的任务之后再执行,也就是采用异步的模式.我们需要将一条消息封装成一个任务,并且将它添加到任务队列里面.后台会运行多个工作进程(worker process),通过调度算法,将队列里的任

js 中arguments的应用

在js中每个函数类都有一个Arguments对象实例arguments,.首先他不是一个数组,可以说算一个伪数组,但是用数组的索引形式也能获取到他的值,如 let len = arguments.length;表示函数参数的个数 arguments[0]表示第一个参数 在函数中使用它的好处就是这个函数在多处调用且参数有不是必须传递的,这样可以利用arguments来处理,解决了不需要的参数也要传递的问题 在实际应用中分装的函数中使用了一下,有不对的和需要改进的地方,还请大家多多指教,一起学习 e