我正在创建一个幻灯片,它将在计时器上运行(由进度条显示),但允许用户单击箭头来强制下一步。我试图使用尽可能多的CSS3,所以我的循环计时器,我使用CSS3动画的进度条。
它的工作方式是,我开始我的进度条在width:0
,并将其设置为width:100%;
。它有一个CSS3 transition
或5s
。然后我观察动画的结束,并使用它来调用我的resetprogress
和changeimage
函数,之后我再次开始进程。它会无限循环。
我已经创建了一个简化的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')