【问题标题】:jQuery delay() - how to stop it?jQuery delay() - 如何停止它?
【发布时间】:2011-12-17 06:34:24
【问题描述】:

我已经尝试过 stop(true,true)、stop(true) 和 clearQueue();但这不起作用。

我遇到了快速更换幻灯片的问题,我已经有了一些必须重置所有内容的功能,但它不起作用。

function reset(){
   $('div').clearQueue();
   $('#img').html('').css({'left':0,'right':0,'opacity':1,'z-index':1});
   $('#img2').html('').css({'left':0,'right':0,'opacity':1,'z-index':1});
   $('#place').html('');$('#place').html('<div id="img"></div><div id="img2"></div>');
}

但我认为这不会停止(或删除)动画上的 delay() 函数。所以我不知道我是否不必使用 setTimeout 函数。

这是一段动画脚本:

reset();
actual_slide=2;
  $('#img').html('<img src="'+image[4]+'" alt="Obrázek">').css({'opacity':0,'z-index':2}).delay(time_delay/5).fadeTo(time_fast,1).delay(time_delay*2).fadeTo(time_fast,0);
  $('#img2').html('<img src="'+image[3]+'" alt="Obrázek">').css({'opacity':'0','top':0}).fadeTo(time_fast,1).animate({'top':'-495'},time_delay*3,function(){
    if(actual_slide==2){$('#img2').css({'top':0}).fadeTo(time_fast*2,0).html('');}else{reset();}
    if(actual_slide==2){$('#img').html('<img src="'+image[3]+'" id="1" alt="Obrázek">').fadeTo(time_fast*2,'1').css({'left':-300,'top':-700}).animate({'left':-900,'top':-700},time_delay*2);}else{reset();}
    if(actual_slide==2){$('#1').css({'width':1365,'height':1200}).animate({'width':1665,'height':1400},time_delay*2);}else{reset();}
  });                          

actual_slide 必须在重复该功能之前对其进行保护,但这也不起作用。问题是当我快速更换幻灯片时,因为重置不会停止一切,它会开始做我不做的事情想拥有(比如把图片换成其他的和其他的)。

【问题讨论】:

  • bugs.jquery.com/ticket/6150 -- 看起来他们已经在 jQuery 1.7 候选版本中修复了这个问题。下载它并查看它是否能解决您的问题,或阅读错误报告以了解一些可能的解决方法。
  • 另外:jQuery: delay() or timeout with stop()?的可能重复
  • 我刚刚尝试过,它适用于 jQuery 1.8.3。

标签: jquery delay settimeout jquery-animate


【解决方案1】:

你可以通过.dequeue()函数打破.delay()

这里是例子

//this is only for make sure that we skip 'delay', not other function
var inDelay = false;

function start()
{
    $('.gfx').animate
    ({
        width: 100
    }, function(){inDelay = true}).delay(3000).animate
    ({
        width: 0
    }, function(){inDelay = false})
}

function breakTheDelay()
{
    if(inDelay)
    {
        $('.gfx').dequeue();
    }
}

http://jsfiddle.net/wasikuss/5288z/

//编辑:提供更复杂的示例,提供日志记录时间戳和清理(没有清理,多次点击Start 是不可预测的)以证明它有效

http://jsfiddle.net/q0058whc/

以下

//this is only for make sure that we skip 'delay', not other function
var inDelay = false;
var ltime = 0;

// console log will aways show 'end' values: 2000, 1000 an 400
// values may be different due to time wasted on calling functions
// sometimes delay is shorten by 0-200ms, it can be caused by js engine probably  

function start()
{
    cleanup();
    ltime = (1*new Date());
    $('.gfx').queue('fx', function(next)
    {
      logtime( 'animate1_start' );
    	$('.gfx').animate
      ({
          width: 100
      }, 2000, function(){logtime('animate1_end');inDelay = true;})
      next();
    })
    .queue('fx', function(next)
    {
    	logtime('delay_start');
    	next()
    })
    .delay(1000)
    .queue('fx', function(next)
    {
    	logtime('delay_end');
    	next()
    })
    .queue('fx', function(next)
    {
    	logtime('animate0_start');
    	$('.gfx').animate
      ({
          width: 0
      }, function(){logtime('animate0_end');inDelay = false;})
      next()
    });
}

function cleanup()
{
		// remove current queue
    $('.gfx').clearQueue()
    // first animate runned interval. stop it 
    .stop()
    // reset width of element
    .css('width',0)
}

function logtime( name )
{
	var ntime = (1*new Date());
	console.log( name + ': ' + ( ntime - ltime ) );
  ltime = ntime;
}

function breakTheDelay()
{
    if(inDelay)
    {
        $('.gfx').dequeue();
    }
}

//
// version without 'inDelay' check only if you know what are you doing
// http://jsfiddle.net/wasikuss/hkw9H/
//
.gfx
{
    background: red;
    width: 0;
    height: 10px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button onclick="start()">Start</button>
<button onclick="breakTheDelay()">Can't wait!</button>
<div class="gfx"></div>

【讨论】:

  • 如果你玩这个,你会看到 dequeue 取消了延迟的最终结果,但没有取消延迟。在显示的示例中,您可以取消动画,但如果您在 3 秒内再次单击,则延迟仍在运行并且动画再次取消。
  • 不!如果您点击“等不及了!”在动画期间,然后“开始”它不会像您预期的那样工作。等待动画完成,然后在延迟期间按“等不及了!”和“开始”。它应该返回并再次将宽度设置为 100 像素。
  • 不,这不能完全工作,只是尝试快速单击这两个按钮而不是单击开始,动画不会等待适当的时间,并且会立即来回移动或有一些奇怪的延迟
  • 这个答案不正确......延迟没有停止。 demo。多次单击提示并继续单击停止。它并没有阻止延迟。撤回我的投票。
  • @MaxYari,是的,因为Start 不关心当前队列。问题是“如何停止 .delay()”,没有“如何编写应用程序并防止多次点击”。如果等待第一个动画结束,则有 3 秒延迟。点击Stop 打破它。我将添加具有更多保护的修改示例...
【解决方案2】:

来自 jQuery delay 页面:

.delay() 方法最适合在队列 jQuery 之间进行延迟 效果。因为它是有限的——例如,它没有提供一种方法来 取消延迟——.delay() 不是 JavaScript 原生的替代品 setTimeout 函数,可能更适合某些用途 案例。

看看doTimeout插件;它可能就是你要找的东西。

我希望这会有所帮助!

【讨论】:

  • 感谢您的回答,我用正常的 setTimeout 尝试了它,现在它几乎可以工作了。但现在我必须以某种方式同步两个计时器。
  • 我不明白为什么 jQuery 停止方法也不会停止延迟。 +1 虽然 - 使用 doTimeout 插件解决了我的问题。
  • 尝试将 setTimeout 与队列和动画一起使用时出现问题,因为 requestAnimationFrame 两者可能不同步。
【解决方案3】:

通过this post有一个非常简单的方法,就是用.animate代替.delay

【讨论】:

  • 作为参考,万一该页面消失,'arniarent' 写道:我通过使用 animate() 代替 delay() 找到了解决问题的方法:$('#element').stop(true,false).animate({opacity:1},200,'easeOutExpo').animate({opacity:1},2000).animate({opacity:0},1000,'easeInQuint');animate({opacity:1},2000)在这种情况下,作为delay(2000) 工作,但可以取消。
  • 我使用了.fadeTo(delayMs, 1),它是.animate 调用的较短版本。我真的很想知道为什么 delay bug 在 4 年前仍然是一个问题时被标记为已修复,以及为什么 .delay 不能只使用引擎盖下的动画来解决这个问题。
  • 延迟错误已修复-您只需要stop(true),因为没有它您只会停止延迟,队列的其余部分可以继续。 stop(false) 如果您只想跳过延迟然后继续其他排队的动画,那将是有意义的。
【解决方案4】:

我希望用户一次又一次地快速重新启动动画链,有时是在动画中间。所以我没有使用delay(),而是使用了一个伪造的css属性{"null":1}。这是一个简单的淡入/淡出。似乎对我有用!

//- fade in
$el.stop().animate({"opacity":1}, 200, "easeInSine", function(){
    //- delay for 2000ms
    $el.stop().animate({"null":1}, 2000, function(){
        //- fade out
        $el.stop().animate({"opacity":0}, 1000, "easeInOutSine", function(){
            //- final callback
        });
    });
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-14
    • 1970-01-01
    • 2011-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-22
    相关资源
    最近更新 更多