我正在尝试使用javascript和jQuery找出停止/启动按钮。我有一个jsfiddle设置试图理解它,但我不能让它工作:http://jsfiddle.net/kkx7m88c/
开始按钮应每次将每个框变为红色。停止按钮应将所有框恢复为蓝色并再次停止变为红色,直到再次按下开始按钮。目前,停止按钮将所有框都变为蓝色,但不会停止播放功能,这意味着尚未变为红色但尚未停止的框。他们变红了。
这是我的js:
// new class turns the boxes red with css
function goClasses(item, container) {
$(container).removeClass('stopped');
$(item).addClass('new');
}
function stopClasses(item, container) {
$(item).removeClass('new');
$(container).addClass('stopped');
}
$('#go').mousedown(function () {
$('.box').each(function(i){
var item = $(this);
var container = $('.selection');
setTimeout(function () {
goClasses(item, container);
}, 500 * i);
if ($(container).hasClass('stopped')) {
//clearTimeout(); /* this doesn't appear to do anything */
//return false; /* this stops the 'go' button from working properly when clicked again after the 'stop' button has clicked */
}
});
});
$('#stop').mousedown(function () {
$('.box').each(function (i) {
var item = $(this);
var container = $('.selection');
stopClasses(item, container);
});
});
我的理解是,如果我可以结束setTimeout和mousedown部分中的.each它会起作用......但也许我完全关闭它。也许我应该使用setInterval()代替?我是jQuery的新手,所以我还在搞清楚这一切!
答案 0 :(得分:2)
存储对计时器的引用并取消它
$('#go').mousedown(function () {
$('.box').each(function(i){
var item = $(this);
var container = $('.selection');
var timer = setTimeout(function () { //store the id that the setTimeout returns
goClasses(item, container);
}, 500 * i);
item.data("timer", timer); //store it as a data attribute
});
});
$('#stop').mousedown(function () {
$('.box').each(function (i) {
var item = $(this);
window.clearTimeout(item.data("timer")); //check the data attribute for the timer and cancel it
var container = $('.selection');
stopClasses(item, container);
});
});
答案 1 :(得分:0)
您可以通过利用jQuery的setTimeout()
和.delay()
完全避免.promise()
。
这样做的好处是你可以使用jQuery的.stop()
来消除延迟并停止整个过程。
function goClasses($item, $container) {
$container.removeClass('stopped');
$item.addClass('new');
}
function stopClasses($item, $container) {
$item.removeClass('new');
$container.addClass('stopped');
}
$('#go').on('click', function () {
var $selection = $(".selection");
if(!$selection.data('running')) {
$('.box').get().reduce(function(p, box) {
return p.then(function() {
var $box = $(box);
goClasses($box, $selection);
return $box.delay(500).promise();
});
}, $.when());
$selection.data('running', true);
}
});
$('#stop').on('click', function () {
stopClasses($('.box').stop(), $('.selection').data('running', false));
});
还包括一种机制,可以让“go”按钮更好地表现,以防用户在动画序列正在进行时再次点击它。
<强> DEMO 强>
<强>解释强>
这个答案采取的方法是合理的,所以如果你不能立即掌握,请不要担心。
如果您不熟悉jQuery的Deferreds / Promises,那么您需要对Deferred Object进行一些背景阅读,并注意.promise()方法可以提供与完成动画(包括延迟)。
您还需要了解javascript的Array.prototype.reduce()方法。
此anwer的核心是$('.box').get().reduce(...)
,它创建了一个.box
元素数组,然后处理该数组以构建一个使用$.when()
返回的已解析jQuery承诺的承诺链。
当链中的每个promise都变为满足(表示动画步骤完成)时,执行下一步,其可见方面为goClasses($box, $selection)
。声明return $box.delay(500).promise()
强制规定步骤之间需要500毫秒的延迟。
“停止”流程只需在所有.stop()
元素上调用.box
,使任何待处理的.delay(500)
无效,并确保相关的承诺永远不会得到满足。动画序列停止。
管理$('.selection').data('running')
布尔值,以指示动画是否正在运行(并重置)。当true
时,此布尔值用于禁止启动另一个动画序列。
我刚刚意识到$('.selection').data('running')
没有必要。我可以测试$('.selection').hasClass('stopped')
而不是