jQuery取消先前排队的事件处理程序来重新启动CSS动画



我正在创建一个幻灯片,它将在计时器上运行(由进度条显示),但允许用户单击箭头来强制下一步。我试图使用尽可能多的CSS3,所以我的循环计时器,我使用CSS3动画的进度条。

它的工作方式是,我开始我的进度条在width:0,并将其设置为width:100%;。它有一个CSS3 transition5s。然后我观察动画的结束,并使用它来调用我的resetprogresschangeimage函数,之后我再次开始进程。它会无限循环。

我已经创建了一个简化的jsFiddle,以显示我正在谈论的内容:http://jsfiddle.net/a3H9L/

简化版本的代码如下。正如您所看到的,我调用startProgress,其中我通过改变宽度来启动CSS3动画,然后为该动画的结束设置一个监视器,此时我重置,然后重新开始。

startProgress();
function startProgress() {
    $('div').width('100%');
    $('div').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend',function(e){
        resetProgress();
        startProgress();
    });
}
function resetProgress (){
    $('div').addClass('notransition'); // Disable transitions
    $('div').width('0');
    $('div')[0].offsetHeight; // Trigger a reflow, flushing the CSS changes
    $('div').removeClass('notransition'); // Re-enable transitions
}
$('button').click(function(event){
    resetProgress();
    startProgress();
});

我的问题是,如果用户点击重置(这将最终是下一步和上一个),我如何在重置和开始一个新的循环之前打破原来的循环?现在,我认为我正在开始一个新的循环,而没有结束原来的循环,这使我同时运行两个循环。

编辑:我认为有些事情是错误的原因是,当我点击重置几次,在循环的事情开始发生在其他时间除了当进度重置。

TL;DR:

在链接.one()之前简单地调用.off()


让我们用你的小提琴做一个实验。

实验1:

每次调用.one()函数时,使用控制台记录一条简单的消息:

$('div').one('...', function(e) {
    console.log('one called!');
    resetProgress();
    startProgress();
});

观察:

是的,你是对的,它们确实堆栈!如果你点击按钮,更多的.one()功能将被添加,并将在动画结束时同时发射。一旦动画完成以下和随后的时间,所有它们仍然会着火!

。运行小提琴,点击你的按钮五次。在第一个动画完成时,控制台记录6条消息(5 + 1)。条形条重置自己并产生另外6条消息。以6的倍数进行


实验2:

现在,让我们尝试在函数开始时关闭它自己:

$('div').one('...', function(e) {
    $(this).off(e);
    console.log('one called!');
    resetProgress();
    startProgress();
});

观察:

这并没有产生我们所期望的抵消效应。与第一次实验结果相同。


实验3:

让我们尝试关闭所有处理程序(通过省略"e"):

$('div').one('...', function(e) {
    $(this).off();
    console.log('one called!');
    resetProgress();
    startProgress();
});

观察:

所有排队的.one()处理程序在动画结束时执行,但它们在运行一次后自行终止,并且在下次动画完成时不触发。


实验4:

你真正想做的是,在设置一个新的处理程序之前取消所有先前排队的处理程序。我们这样做:

$('div').off().one('...', function(e) {
    console.log('one called!');
    resetProgress();
    startProgress();
});

观察:

这就是你的答案!这个函数现在只运行一次,因为之前的处理程序在放置新处理程序之前被取消设置。在链接.one()之前简单地调用.off()


免责声明:

这些实验假设这些是元素上仅有的事件处理程序。如果您有.on(), .one()或类似设置的附加处理程序,而不是使用.off()来清除所有内容,您必须指定要清除哪些处理程序,如下所示:

.off('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend')

相关内容

  • 没有找到相关文章

最新更新