关于伸缩菜单js代码正确实现
2017-03-29 12:13
477 查看
今天在imooc上看的伸缩菜单的js实现 http://www.imooc.com/video/93
自己实践的时候发现这个代码是有问题的。 先上错误代码
这个代码忽略了两个问题。
1.如果鼠标悬浮瞬间离开,到空白处(即长度未增加多少的时候),多来几次,即可能造成无限循环
原因:离开时,悬浮变长的动作还没完,悬浮时,离开减小的动作还没完,发生冲突,某个时刻满足循环条件会出现动画循环
2.如果鼠标悬浮瞬间离开,到另一个list处,多试几次,会发生什么? 我们也是可以看到无限循环动画的发生。
原因 把增减动画都归类到了 obj.time属性里面。如果按2到操作,极有可能出现在某一时刻同一obj增减到冲突,本来应该减的,但是增的动作还没完,就会一直增,导致减也也完成不了
解决办法 :1------》在鼠标悬浮函数开头清空鼠标离开的所有动画,在鼠标离开函数开头清空鼠标悬浮的所有动画
2--------》 鼠标悬浮和离开这两个动画应该分开,不能用同一个属性,要分别用两个属性表示(最后面讲一讲为什么要用属性,不能用全局变量,不能用局部变量,同时也讲一下为什要用v a r T his= this)
正确代码如下:
为什么用属性?
首先我们肯定不能用局部变量,在内部函数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绑定的对象还没有变化
自己实践的时候发现这个代码是有问题的。 先上错误代码
<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绑定的对象还没有变化
相关文章推荐
- JS实现横向拉伸动感伸缩菜单效果代码
- JS实现横向拉伸动感伸缩菜单效果代码
- 收缩展开的竖直菜单(利用JS+CSS实现_网页代码站(www.webdm.cn)
- 纯CSS无JS实现灰色下拉导航菜单代码
- js下拉框二级关联菜单效果代码具体实现
- js实现的黑背景灰色二级导航菜单效果代码
- 4行代码简单实现js树形菜单
- Js+Css打造的红色经典伸缩菜单代码
- js捕获鼠标右键菜单中的粘帖事件实现代码
- js下拉框二级关联菜单效果代码具体实现
- 4行代码简单实现js树形菜单
- js实现的简洁网页滑动tab菜单效果代码
- JS特效代码(三)可折叠的自动伸缩菜单
- JS无限级菜单代码,与CSS结合实现
- js实现收缩菜单效果实例代码
- [置顶] 4行代码简单实现js树形菜单
- DIV+JS实现可展开、折叠的菜单代码
- 关于js的接口和 继承实现的代码例子
- js实现 菜单iframe与主页面iframe 重叠 防止互相遮挡 代码参考