【问题标题】:pause and resume array of setTimeouts暂停和恢复 setTimeouts 数组
【发布时间】:2013-12-03 06:29:46
【问题描述】:

我在这里找到了关于如何暂停和恢复 setTimeout 的好答案。很有用。

但是如何解决一个类似的问题,但要使用 setTimeouts 数组? 我需要单击任何元素以暂停,然后在单击上次停止的数组中的 setTimeout 后恢复,依此类推。

到目前为止,我的代码可以正常工作,只是它会在开始时恢复超时设置。有没有办法检查哪个 setTimeout 元素暂停并在此时再次恢复?我认为 var fadeTrailer 的第二个定义必须减去那些已经激活的元素。不知何故,它应该与索引一起使用。但我不知道怎么做。感谢您的帮助!

//automatic fader
fadeTrailer = [

        setTimeout( function() {
            //first action
        }, 9500),

        setTimeout( function() {
            //second action )   
        }, 19000),

        setTimeout( function() {
            //third action  
        }, 32000),

];

$("#Trailer").on( 'click.resumeTrailerFade', function() { resumeTrailerFade(); } ); 

功能恢复

function resumeTrailerFade() {

$.each( fadeTrailer, function(i, timer) {
    clearTimeout(timer);
} );

fadeTrailer = [

    setTimeout( function() {
        //first action
    }, 9500),

    setTimeout( function() {
        //second action )   
    }, 19000),

    setTimeout( function() {
        //third action )    
    }, 32000),          
];

};

我希望这是在这里执行此操作的正确方法。对初学者来说很好但也很困难的论坛;-) 我现在所做的是,我在开始时声明了一个时间轴变量:

var fadingTimeline = [

setTimeout( function() {
    //anything
fadeState = 0;
}, 9500),

setTimeout( function() {
    //anything
    fadeState = 1;  
}, 19000),

setTimeout( function() {
    //anything
    fadeState = 2;  
}, 32000),

];

那我先出场了:

//automatic fader
                    fadeTrailer = fadingTimeline;

                    // interrupts automatic fader and restarts it (to give user time to stay on each work when clicking elements in it)                     
                    $("#Trailer").on( 'click.resumeTrailerFade', function() { resumeTrailerFade(); } ); 

然后对于 resumeTrailerFade() 我尝试使用 fadeState 变量按索引 grep 元素数组,例如:

function resumeTrailerFade() {

$.each( fadeTrailer, function(i, timer) {
    clearTimeout(timer);
} );

//filter timeline array for already passed setTimeouts
fadeTrailerRemain = $.grep( fadingTimeline, function(n) {
    return ( n.index < fadeState );
});

}

我知道最后一部分是愚蠢的代码,只是为了解释我的想法。 是否有人能够遵循我的想法并将其放入真正的工作代码中?太棒了!

【问题讨论】:

  • 当您创建超时时,您可以将超时保存在变量中,例如:var t1 = setTimeout(); ....然后你可以将它们保存在一个数组中,如果暂停则添加一个标志
  • 我想您是在问如何将 fadeTrailer 索引传递给 resumeTrailerFade?你能发布你的标记吗?
  • 是的,我看到了这个答案,如果只有一个 setTimeout,我可以将它用于我的目的,但我在这里有一组 setTimeouts,所以我问如何为此调整类似的任务。到目前为止,感谢您提供有趣的 cmets!我会尝试了解这些标志。
  • 我在最后的原始问题中添加了一个新代码

标签: javascript jquery settimeout resume


【解决方案1】:

已编辑:不知何故,我错过了 Igoel 的评论,他说了同样的话。对此感到抱歉。

没有简单的方法可以查询超时以查看已经过去了多少时间。您可以将超时的开始时间存储在单独的变量中,然后显式计算差异。

FWIW,请注意 JavaScript 超时不一定准确,因为 JavaScript 是单线程执行环境。

【讨论】:

    【解决方案2】:

    您向我展示的代码实际上对我来说很棒! 我改变了一点(因为我不需要按钮等) 所以我这样声明变量:

    var first = function() {
      // do the first thing
    }
    var second = function() {
      // do the second thing
    }
    var third = function() {
      // do the third thing
    }
    var fourth = function() {
      // do the fourth thing
    }
    var fifth = function() {
      // do the fifth thing
    }
    //…
    
    var timer;
    var timeFrames = {
      95: [first],
      190: [second],
      320: [third],
      420: [fourth],
      510: [fifth],
      //…
    };
    var timerPaused = false;   
    var maxStep = 510;
    var stepSize = 100;
    var currentStep = 0;
    
    var intervalTimer = function() {
    
    if ( !timerPaused ) { currentStep ++; }
    if ( !!timeFrames[currentStep] ) {
        if ( !!timeFrames[currentStep][0] ) {
            ( timeFrames[currentStep][0])(timeFrames[currentStep][1] );
        }
    }
    if ( currentStep >= maxStep ) {
        timer = window.clearInterval(timer);   
        currentStep = 0;
      } 
    }  
    

    在我需要它的函数内的正确位置,所以我把它自动启动:

    //automatic trailer fader                       
    timer = window.setInterval( intervalTimer, stepSize );
    // interrupts automatic fader 
    // restarts it (to give user time to stay on clicked elements within the fading content)
    $("#Trailer").on( 'click.resumeTrailerFade', function() { 
      timerPaused = true;
      setTimeout( function() { timerPaused = false; }, 15000 ); // give some extra time when anything clicked before resume automatic fade again
    } );
    

    然后终于把我放的都废掉了:

    //stops automatic trailer fader definitely without resume
    timerPaused = true;
    window.clearInterval(timer);
    $("#Trailer").off( 'click.resumeTrailerFade' );
    

    工作完美,即使我知道对你们教授来说可能还有一些奇怪的东西。 因此,请随时发表评论。欢迎大家帮忙改进!

    到目前为止,感谢您的大力帮助,没有它我永远不会成功。

    【讨论】:

    • 看起来不错,我个人会将这些 var timeFrames = { 95: [first], //… }; if ( !!timeFrames[currentStep][0] ) { ( timeFrames[currentStep][0])(timeFrames[currentStep][1] ); } 更改为这些 var timeFrames = { 95: first, //… }; if ( !!timeFrames[currentStep] ) { ( timeFrames[currentStep])(timeFrames[currentStep][1] ); } 因为您不使用参数而且我想知道为什么您最后清除了 timeOut,这已经发生在 maxstep已到达。
    • 谢谢,我改变了变量,所以最终得到了 var intervalTimer = function() { if ( !timerPaused ) { currentStep ++; } if ( !!timeFrames[currentStep] ) { ( timeFrames[currentStep] )( timeFrames[currentStep][1] ); } if ( currentStep >= maxStep ) { timer = window.clearInterval(timer);当前步长 = 0; } } 正确的? 2) 你的意思是window.clearInterval(timer);在代码的第三部分?这是为了在结束之前中断(在另一个必须绝对杀死自动推子的地方,以免与外面的功能混淆
    • 你快到了,这将起作用,但是假设你在第 190 步,它的值是“秒”,所以你正在调用“秒(秒 [1])”,结果是“ second(undefined)" 方括号中的数字是因为 framevalues 曾经是 "[,]" 意味着它是一个数组 我希望我已经解释清楚了,我建议你看看 json 表示法和 javascript 数组。我的观点是你可以改变'( timeFrames[currentStep] )(timeFrames[currentStep][1]);' to: '( timeFrames[currentStep] )();'.
    • 对于我作为设计师(艺术家:-))来说,很难理解所有的解释,但我会尝试更多地研究数组。无论如何,感谢您的大力帮助。我新改了代码,效果很好!
    • 我明白了,你是设计师。您是否考虑过使用像 jQuery 这样的库?在我看来,您正试图淡出一个元素,jQuery 对于这样的事情非常有用。
    猜你喜欢
    • 2013-07-19
    • 2015-07-28
    • 2014-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多