关于伸缩菜单js代码正确实现

今天在imooc上看的伸缩菜单的js实现 http://www.imooc.com/video/93

自己实践的时候发现这个代码是有问题的。     先上错误代码

<ul>
    <li style="background-color: red; width: 100px">第一个</li>
    <li style="background-color: red; width: 100px">第二个</li>
    <li style="background-color: red; width: 100px">第三个</li>
</ul>
<script type="text/javascript">
    window.onload = function () {
        var ls = document.getElementsByTagName("li");
        for (var i = 0; i < ls.length; i++) {
            ls[i].onmouseover = function () {
                var This = this;
                This.time = setInterval(function () {
                        This.style.width = This.offsetWidth + 20 + "px";
                   if(This.offsetWidth >= 160){
                        This.style.width = 160 + "px";
                       clearInterval(This.time);
                    }
                }, 30)
            };}
        for (var i = 0; i < ls.length; i++) {
            ls[i].onmouseout = function () {
                var This = this;
                This.time= setInterval(function () {
                        This.style.width = This.offsetWidth - 20 + "px";
                    if(This.offsetWidth <=100) {
                        This.style.width = 100 + "px";
                        clearInterval(This.time);
                    }
                }, 30)
            };
        }
    }
</script>

这个代码忽略了两个问题。

1.如果鼠标悬浮瞬间离开,到空白处(即长度未增加多少的时候),多来几次,即可能造成无限循环

原因:离开时,悬浮变长的动作还没完,悬浮时,离开减小的动作还没完,发生冲突,某个时刻满足循环条件会出现动画循环

2.如果鼠标悬浮瞬间离开,到另一个list处,多试几次,会发生什么? 我们也是可以看到无限循环动画的发生。

原因 把增减动画都归类到了 obj.time属性里面。如果按2到操作,极有可能出现在某一时刻同一obj增减到冲突,本来应该减的,但是增的动作还没完,就会一直增,导致减也也完成不了

解决办法 :1------》在鼠标悬浮函数开头清空鼠标离开的所有动画,在鼠标离开函数开头清空鼠标悬浮的所有动画

2--------》 鼠标悬浮和离开这两个动画应该分开,不能用同一个属性,要分别用两个属性表示(最后面讲一讲为什么要用属性,不能用全局变量,不能用局部变量,同时也讲一下为什要用v a r  T his= this

正确代码如下:

<script type="text/javascript">
    window.onload = function () {
        var ls = document.getElementsByTagName("li");
        for (var i = 0; i < ls.length; i++) {
            ls[i].onmouseover = function () {   //内部函数1
                var This = this;
                clearInterval(This.off);
                This.on = setInterval(function () {			
                        This.style.width = This.offsetWidth + 20 + "px";
                   if(This.offsetWidth >= 160){
                        This.style.width = 160 + "px";
                       clearInterval(This.on);
                    }
                }, 30)
            };}
        for (var i = 0; i < ls.length; i++) {
            ls[i].onmouseout = function () {   //内部函数2
                var This = this;
                clearInterval(This.on)
                This.off = setInterval(function () {
                        This.style.width = This.offsetWidth - 20 + "px";    
                    if(This.offsetWidth <=100) {
                        This.style.width = 100 + "px";
                        clearInterval(This.off);
                    }
                }, 30)
            };
        }
    }
</script>

为什么用属性?

首先我们肯定不能用局部变量,在内部函数2(1)肯定无法访问内部函数1(2)的局部变量,那么就没办法清除“动画栈”里的动画了

为什么不用全局变量 o n 、o f f.   我们考虑一种情况。假设我从listA快速移到listB。 此时on表示增加的动画 off表示减小的动画

离开A到B的一瞬间  B触发onmouseover   执行clearInterval(off) A还没来得及减小到原来的长度就被迫停止了

换句话说 如果用全局变量从此动画不在区分是针对哪个对象的动画

为什么用var This = this ?

  set interval是延时函数。执行的时候this已经变成了window 而我们想要this绑定到list上 所有用变量This储存lIst 的地址,因为执行var This = this.this绑定的对象还没有变化










 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值