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减小这样的效果,有什么方法?
又看了下代码: 发现了其实主要是没能有效的清除定时器的问题,把代码改成下面这样就可以运行。
<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函数合并在一起代码会更简洁。
为了让问题更清晰,我把代码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); } } } }
实际上只需要把onmouseover和onmouseout改成onmouseenter和onmouseleave就行了,over和out指代的是鼠标经过和移出,实际上你从div移动到span中按道理来说还是在div内,但是因为涉及了span的移入移出则会出现事件冒泡。换成enter和leave(穿入穿出)后不会触发span事件,所以不会出问题,你可以试试
把你的计时器settimeout换成setInterval看看,虽然两个方法都是延时加载,但是作用有所不同
JS动画效果
113920 学习 · 1450 问题
相似问题