发新贴  快速回复

clearTimeout的问题

WEB开发工程师
2014-02-09 18:52
清楚定时器这个有作用域吗
我写了个简单的二级导航,发现clearTimeout不太好用,如果不是在鼠标移入的时候清楚定时器就好用,这是为什么?语言可能不太好理解,下面是代码,纠结了好长时间,不知道什么原因

///  css
*{margin:0;padding:0;}
li{list-style:none;float:left;padding:0 20px;position:relative;border:1px solid red;}
li p{display:none;position:absolute;top:30px;}


// html
<ul id="nav">
        <li><a href="###">首页</a>
                <p>
                        <a href="###">首页</a><br/>
                        <a href="###">首页</a><br/>
                        <a href="###">首页</a><br/>
                </p>
        </li>
        <li><a href="###">首页</a>
                <p>
                        <a href="###">首页</a><br/>
                        <a href="###">首页</a><br/>
                        <a href="###">首页</a><br/>
                </p>
        </li>
        <li><a href="###">首页</a>
                <p>
                        <a href="###">首页</a><br/>
                        <a href="###">首页</a><br/>
                        <a href="###">首页</a><br/>
                </p>
        </li>
</ul>


//  JS

<script type="text/javascript">
var oUl=document.getElementById('nav');
var aLis=oUl.getElementsByTagName('li');
var timer='';
for(var i=0;i<aLis.length;i++){
        aLis.err==function(){
                var oP=this.getElementsByTagName('p')[0];
                oP.style.display='block';
        }
        aLis.err==function(){
                var oP=this.getElementsByTagName('p')[0];
                timer=setTimeout(function(){
                        oP.style.display='none';
                },2000);
                //clearTimeout(timer);   这里清楚定时器就好使
                oP.err==function(){
                        clearTimeout(timer);  // 这里清楚定时器就不好使,这是为什么???求解
                }
        }
}
</script>

先谢谢各位了  
win7killer
for循环里边没报错??
2014-02-09 19:25  回复本帖
WEB开发工程师
forum.php?mod=redirect&goto=findpost&pid=24016&ptid=7648
for循环里边没报错??

没报错啊   为什么会出现这种情况?
2014-02-09 19:48  回复本帖
创美易-miaov
 本帖最后由 创美易-miaov 于 2014-2-10 02:30 编辑 

aLis.err= 改成 aLis【i】.onmouseover      out也一样。 

鼠标移入p标签上也算是移开aLis的,当你快速划过3个aLis,你发现他们不能隐藏。

应该是多个aLis共用了一个定时器,所以清除不了。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
 <style>
     *{margin:0;padding:0;}
     ul{margin: 100px}
     li{list-style:none;float:left;padding:0 20px;position:relative;border:1px solid red;}
     li p{display:none;position:absolute;top:30px;}
 </style>
</head>
 <body>
 <ul id="nav">
     <li><a href="###">首页</a>
         <p>
             <a href="###">首页</a><br/>
             <a href="###">首页</a><br/>
             <a href="###">首页</a><br/>
         </p>
     </li>
     <li><a href="###">首页</a>
         <p>
             <a href="###">首页</a><br/>
             <a href="###">首页</a><br/>
             <a href="###">首页</a><br/>
         </p>
     </li>
     <li><a href="###">首页</a>
         <p>
             <a href="###">首页</a><br/>
             <a href="###">首页</a><br/>
             <a href="###">首页</a><br/>
         </p>
     </li>
 </ul>
 <script>
     var oUl=document.getElementById('nav');
     var aLis=oUl.getElementsByTagName('li');
     var timer=null;
     for(var i=0;i<aLis.length;i++){
         aLis[i].timer = null;
         aLis[i].err==function(){
             clearTimeout(this.timer);
             var oP=this.getElementsByTagName('p')[0];
             oP.style.display='block';
         }
         aLis[i].err==function(){
             var oP=this.getElementsByTagName('p')[0];
             this.timer=setTimeout(function(){
                 oP.style.display='none';
             },1000);
             //clearTimeout(timer);   这里清楚定时器就好使
             /*oP.err==function(){
                 clearTimeout(timer);  // 这里清楚定时器就不好使,这是为什么???求解
             } */
         }
     }
 </script>
 </body>
</html>
2014-02-09 21:15  回复本帖
WEB开发工程师
forum.php?mod=redirect&goto=findpost&pid=24019&ptid=7648
aLis.err= 改成 aLis【i】.onmouseover      out也一样。 

鼠标移入p标签上也算是移开aLis的,当你 ...

还是不太明白  为什么要在aLis[i].onmouseover的时候清除定时器
2014-02-10 10:39  回复本帖
win7killer
forum.php?mod=redirect&goto=findpost&pid=24024&ptid=7648
还是不太明白  为什么要在aLis.err=的时候清除定时器

因为P的mouseover会冒泡到aLis上边触发aLis的mouseover事件,这样就能触发clearTimeout
2014-02-10 15:16  回复本帖
创美易-miaov
forum.php?mod=redirect&goto=findpost&pid=24024&ptid=7648
还是不太明白  为什么要在aLis.err=的时候清除定时器

就是把上一个定时器清除一下,避免造成 “打架”,鼠标移入p标签上也算是移开aLis的
2014-02-10 15:57  回复本帖
WEB开发工程师
forum.php?mod=redirect&goto=findpost&pid=24028&ptid=7648
因为P的mouseover会冒泡到aLis上边触发aLis的mouseover事件,这样就能触发clearTimeout ...

非常感谢   谢谢  谢谢
2014-02-10 18:17  回复本帖
WEB开发工程师
forum.php?mod=redirect&goto=findpost&pid=24029&ptid=7648
就是把上一个定时器清除一下,避免造成 “打架”,鼠标移入p标签上也算是移开aLis的 ...

非常感谢   谢谢  谢谢
2014-02-10 18:18  回复本帖
WEB开发工程师
forum.php?mod=redirect&goto=findpost&pid=24028&ptid=7648
因为P的mouseover会冒泡到aLis上边触发aLis的mouseover事件,这样就能触发clearTimeout ...

你说的这个倒是可以理解,但是,为什么在子级的清除定时器就没用呢
2014-02-10 22:35  回复本帖
WEB开发工程师
其实,我发现自己走了弯路了 
下面是代码
// CSS
*{margin:0;padding:0;}
#nav{margin:100px auto 20px;width:156px;height:24px;}
#nav li{list-style:none;float:left;position:relative;width:50px;border:1px solid green;text-align:center;line-height:24px;}
#nav li p{display:none;position:absolute;border:1px solid red;top:40px;left:0;width:50px;text-align:center;}

// HTML
<ul id="nav">
    <li><a href="http://www.baidu.com">门户</a>
        <p>
            <a href="http://www.qq.com">腾讯</a>
            <a href="http://www.163.com">网易</a>
            <a href="http://www.sina.com.cn">新浪</a>
            <a href="http://www.sohu.com">搜狐</a>
        </p>
    </li>
    <li><a href="http://www.alibaba.cn">购物</a>
        <p>
            <a href="http://www.taobao.com">淘宝</a>
            <a href="http://www.tmall.com">天猫</a>
            <a href="http://www.jd.com">京东</a>
            <a href="http://www.paipai.com">拍拍</a>
        </p>
    </li>
    <li><a href="http://www.baidu.com">搜索</a>
        <p>
            <a href="http://g.cn">谷歌</a>
            <a href="http://www.soso.com">搜搜</a>
            <a href="http://www.so.com">360</a>
        </p>
    </li>
</ul>
<div style="border:1px solid pink;">
中华人民共和国
</div>

// JS
<script type="text/javascript">
var oNav=document.getElementById('nav');
var aNavLis=oNav.getElementsByTagName('li');
var aNavP=oNav.getElementsByTagName('p');
for(var i=0;i<aNavLis.length;i++){
    aNavLis[i].err==function(){
        for(var j=0;j<aNavP.length;j++){
            aNavP[j].style.display='none';
        }
        var oP=this.getElementsByTagName('p')[0];
        oP.style.display='block';
        clearTimeout(oP.timer);
    }
    aNavLis[i].err==function(){
        var oP=this.getElementsByTagName('p')[0];
        oP.timer=setTimeout(function(){
            oP.style.display='none';
        },1000);
    }
}
</script>

鼠标移入li的时候,1S之后P就会消失,即便没有执行li的err=事件,依然会消失
所以要在li的err=的时候就清除定时器
这样就已经达到了预期的效果,但是这里又有疑问了
为什么还没有执行li的鼠标移出事件就会触发定时器呢
难道是因为setTimeout是属于window的,它的执行并不依赖于li的鼠标移出?这样理解也不通啊
额  又开始纠结了····
2014-02-11 14:12  回复本帖
登录 后才可以发表回复