如何让我的setTimeouts在这里停止?

时间:2016-03-31 04:46:53

标签: javascript jquery html

我想要实现的行为是:

在悬停/鼠标中心时,将背景图像从占位符更改为位置发生变化的gif以获得动画效果,然后在鼠标离开时返回占位符。

我的代码是

    $('.filmstrip').mouseenter(function(){
        var $that = $(this),
               w = $that.width(),
              fr = $that.attr('data-framerate');
        $that.css('background-image','url('+$that.attr('data-gifurl')+')');
        for ( var i = 1, n = $that.attr('data-ticks'); i <= n; ++i )
        {
            (function(j){
               setTimeout(function(){
                  $that.css('background-position-x','-'+(w*j)+'px');
               }, j*fr);
            })(i);
        }
        $that.bind('mouseleave',function(){
            $that.css('background-image','url('+$that.attr('data-placeholder')+')').css('background-position-x','0');
        });
    }); 

我遇到的错误是如果gif没有完成动画,那么

.css('background-position-x','0')

的一部分
$that.css('background-image','url('+$that.attr('data-placeholder')+')').css('background-position-x','0');
            });

不起作用,因为动画仍在移动背景位置。所以我需要一些方法来首先停止setTimeout的东西,如果它没有完成运行。知道我该怎么做吗?

4 个答案:

答案 0 :(得分:1)

添加一个停止变量:

$('.filmstrip').mouseenter(function(){
    var isStopped = false;
    var $that = $(this),
           w = $that.width(),
          fr = $that.attr('data-framerate');
    $that.css('background-image','url('+$that.attr('data-gifurl')+')');
    for ( var i = 1, n = $that.attr('data-ticks'); i <= n && !isStopped; ++i )
    {
        (function(j){
           setTimeout(function(){
              if (!isStopped) {
                  $that.css('background-position-x','-'+(w*j)+'px');
              }
           }, j*fr);
        })(i);
    }
    $that.bind('mouseleave',function(){
        isStopped = true;
        $that.css('background-image','url('+$that.attr('data-placeholder')+')').css('background-position-x','0');
    });
});

如果isStopped无法从超时访问(因为未经测试),那么只需在内部作用域中创建一个新的变量,它会影响isStopped值。

答案 1 :(得分:1)

您可以使用基于区间的解决方案,例如

&#13;
&#13;
$('.filmstrip').mouseenter(function() {
  var $that = $(this),
    w = $that.width(),
    fr = +$that.attr('data-framerate'),
    ticks = +$that.attr('data-ticks');
  $that.css('background-image', 'url(' + $that.attr('data-gifurl') + ')');

  var counter = 0;
  var interval = setInterval(function() {
    $that.css('background-position-x', '-' + (w * ++counter) + 'px');
    if (counter >= ticks) {
      clearInterval(interval);
    }
  }, fr);
  $(this).data('bg-interval', interval)
}).mouseleave(function() {
  clearInterval($(this).data('bg-interval'));
  $(this).css('background-image', 'url(' + $(this).attr('data-placeholder') + ')').css('background-position-x', '0');
});
&#13;
.filmstrip {
  height: 64px;
  border: 1px solid grey;
  background-position: right;
  background-position-y: inherit;
  display: inline-block;
  width: 64px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="filmstrip" data-framerate="400" data-ticks="10" data-gifurl="//cdn.sstatic.net/Sites/stackoverflow/img/sprites.svg?v=bc7c2f3904bf">
</div>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

使用CSS而不是javascript可能会做得更好。

选项#1 - 使用实际的GIF

您可以将想要动画的帧编译为实际的GIF文件,然后根据悬停情况更改背景图像:

<div class="filmstrip"></div>

然后是CSS

.filmstrip { background:transparent url('static_image.jpg') no-repeat 0 0 }
.filmstrip:hover { background-image:url( 'animated_image.gif' ) }

选项#2 - 使用CSS3动画

您可以将动画图像保持为一条帧(已知长度),然后使用以下内容:

<div class="filmstrip"></div>

使用CSS

.filmstrip { background:transparent url('static_image.jpg') no-repeat 0 0 }
@keyframes animate-bg {  
    0% { background-position: 0 0 }
  100% { background-position: -1000px 0 }
  /* where 1000px is the length of the strip */
}
.filmstrip:hover { animation: animate-bg 5s steps(50) infinite }
/* where 5s is the overall loop length time and 50 is the number of frames in the strip */

选项#3 - 使用Spritely

Spritely是一个jQuery插件,它似乎管理将幻灯片/精灵图像转换为动画的所有元素,包括能够启动/停止动画,重置到第一帧,更改FPS等。

答案 3 :(得分:0)

你可以使用clearTimeout来停止setTimeOut

工作演示 -

&#13;
&#13;
var myVar;

function myFunction() {
    myVar = setTimeout(function(){ alert("Hello"); }, 3000);
}

function myStopFunction() {
    clearTimeout(myVar);
}
&#13;
<p>Click the first button to alert "Hello" after waiting 3 seconds.</p>
<p>Click the second button to prevent the first function to execute. (You must click it before the 3 seconds are up.)</p>

<button onclick="myFunction()">Try it</button>
<button onclick="myStopFunction()">Stop the alert</button>
&#13;
&#13;
&#13;

更多 -

<强> nodetool options.

<强> Mozilla Developer Network