为了账号安全,请及时绑定邮箱和手机立即绑定

动画过程中的bug

根据老师的实现我自己写了一段代码,跟老师的不太一样,但是动画过程中有一定几率出现bug。代码如下:

	<script>
		window.onload=function(){

			var myDiv=document.getElementById('box1');
			var timer=null;
			myDiv.onmouseover=function(event){
				timer=setTimeout(move,30);

				function move(){
					clearTimeout(timer);
					if(myDiv.offsetLeft>=0) return;
					else{
						myDiv.style.left = myDiv.offsetLeft + 5 +'px';
						setTimeout(move,30);
					}
				}
			}

			myDiv.onmouseout=function(event){
				timer=setTimeout(move,30);

				function move(){
					clearTimeout(timer);
					if(myDiv.offsetLeft<=-600) return;
					else{
						myDiv.style.left = myDiv.offsetLeft -5 +'px';
						setTimeout(move,30);
					}
				}
			}

		}
		
		

	</script>

我把div的宽度设置为600px,left值也为-600px,然后执行代码,在动画过程中反复触发鼠标事件。或者直接触摸span标签。有时候动画就一直执行,闪来闪去,不会停止。

我的分析是mouseover的结束条件是left>=0,mouseout的结束条件是left<=-600,当在动画过程中,即mouseover未结束时,又触发了mouseout事件。left的值就可能永远位于-600到0之间。动画就不会停止。

请问大神这样分析对不?有什么方法解除这种bug?

另外如果要实现无论是否在动画执行过程中,鼠标over上时,left就增加,鼠标移开,马上left减小这样的效果,有什么方法?

正在回答

4 回答

又看了下代码: 发现了其实主要是没能有效的清除定时器的问题,把代码改成下面这样就可以运行。

<script>
    window.onload=function(){
        var myDiv=document.getElementById('box1');
        var timer=null;         
        myDiv.onmouseover=function(event){
            move(); 
            function move(){
                clearTimeout(timer);
                if(myDiv.offsetLeft>=0) return;
                else{
                    myDiv.style.left = myDiv.offsetLeft + 5 +'px';
                    timer = setTimeout(move,100);
                }
            }
        }
  
        myDiv.onmouseout=function(event){
            move(); 
            function move(){
                clearTimeout(timer);
                if(myDiv.offsetLeft<=-600) return;
                else{
                    myDiv.style.left = myDiv.offsetLeft -5 +'px';
                    timer = setTimeout(move,100);
                }
            }
        }
    }
</script>

将函数提出来放到事件外面定义效率更高,再将两个move函数合并在一起代码会更简洁。

0 回复 有任何疑惑可以回复我~

为了让问题更清晰,我把代码copy下来,大家可以自己试下效果。 这动画执行过程中多次快速触发鼠标事件,有惊喜哦!!

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
body{margin: 0;padding: 0;}
#box1{
width: 600px;
height: 100px;
background-color: #f00;
left: -600px;
position: relative;
}
#box1 span{
width: 20px;
height: 50px;
background-color: #00f;
position: absolute;
left: 600px;
top: 25px;
}
</style>
</head>
<body>
<div id="box1">
<span id="share">分享</span>
</div>
<script>
    window.onload=function(){
        var myDiv=document.getElementById('box1');
        var timer=null;
        
        myDiv.onmouseover=function(event){
            timer=setTimeout(move,100);
 
            function move(){
                clearTimeout(timer);
                if(myDiv.offsetLeft>=0) return;
                else{
                    myDiv.style.left = myDiv.offsetLeft + 5 +'px';
                    setTimeout(move,100);
                }
            }
        }
 
        myDiv.onmouseout=function(event){
            timer=setTimeout(move,100);
 
            function move(){
                clearTimeout(timer);
                if(myDiv.offsetLeft<=-600) return;
                else{
                    myDiv.style.left = myDiv.offsetLeft -5 +'px';
                    setTimeout(move,100);
                }
            }
        }
 
    }


0 回复 有任何疑惑可以回复我~

实际上只需要把onmouseover和onmouseout改成onmouseenter和onmouseleave就行了,over和out指代的是鼠标经过和移出,实际上你从div移动到span中按道理来说还是在div内,但是因为涉及了span的移入移出则会出现事件冒泡。换成enter和leave(穿入穿出)后不会触发span事件,所以不会出问题,你可以试试

0 回复 有任何疑惑可以回复我~
#1

charsandrew 提问者

谢谢回答。 改成onmouseenter 和 onmouseleave试了下,比前面稍微好了写,但在动画执行过程中多次反复出发 onmouseenter和onmouseout时,依然有时会出现动画卡住的bug。
2017-09-30 回复 有任何疑惑可以回复我~

把你的计时器settimeout换成setInterval看看,虽然两个方法都是延时加载,但是作用有所不同

0 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消
JS动画效果
  • 参与学习       113923    人
  • 解答问题       1443    个

通过本课程JS动画的学习,从简单动画开始,逐步深入各种动画框架封装

进入课程

动画过程中的bug

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信