动画过程中的bug

来源:2-1 JS速度动画

charsandrew

2017-05-30 02:40

根据老师的实现我自己写了一段代码,跟老师的不太一样,但是动画过程中有一定几率出现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回答

  • charsandrew
    2017-10-03 08:13:10

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

    <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函数合并在一起代码会更简洁。

  • charsandrew
    2017-09-30 13:38:15

    为了让问题更清晰,我把代码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);
                    }
                }
            }
     
        }


  • 慕尼黑2796912
    2017-05-31 22:09:30

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

    charsa...

    谢谢回答。 改成onmouseenter 和 onmouseleave试了下,比前面稍微好了写,但在动画执行过程中多次反复出发 onmouseenter和onmouseout时,依然有时会出现动画卡住的bug。

    2017-09-30 13:33:58

    共 1 条回复 >

  • 叶隐狂岚
    2017-05-31 16:37:44

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

JS动画效果

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

113920 学习 · 1450 问题

查看课程

相似问题