var games = [];
var numbers_to_letters = ["one", "two", "three", "four", "five", "six"]
function Game(){
roll_animation();
}
$("#roll_dice").click(function(){
games.push(new Game());
});
function roll_animation(){
for (var i = 0; i < 100; i++){
for (var j = 0; j < 5; j++){
(function(ind){
window.setTimeout(function(){
$(".btn.btn-die").addClass(numbers_to_letters[ind+1]).removeClass(numbers_to_letters[ind]);
}, 20 * (ind + 1));
})(j);
}
$(".btn.btn-die").addClass("one").removeClass("six");
}
}
第一个循环中的最后一行不会被执行,除非我再次按下该按钮,导致第二个循环只运行一次。 (它需要重置才能再次工作)为什么最后一行不会被执行?
答案 0 :(得分:1)
这似乎是setTimeout()
函数中运行一段时间后异步代码的问题,因此与循环中的其他代码不同步。
有问题的代码行:
$(".btn.btn-die").addClass("one").removeClass("six");
运行得很好。但是,因为setTimeout()
调用计划执行一些计时器,所以它们都在上面的行运行之后运行。所以这行代码运行然后setTimeout()
定时器开始触发,上面一行的效果被覆盖。这是您的代码指示它执行的操作。
如果你减慢时间,你可以看看你的密码的这个演示中发生了什么:http://jsfiddle.net/jfriend00/tqYq7/
如果,你想要的是上一行定时器触发后运行上面的代码行,那么你需要编写代码来代替你现在编写的代码。我不清楚你要用这行代码做什么,所以我不确定究竟推荐什么。
有人可能会问你为什么要设置500个计时器,其中大部分计时器会在同一时间运行并运行完全相同的代码?肯定有更有效的方式以经常性的方式运行某些东西。如果你真正要做的就是一个接一个地运行内部动画100次,那么你将不得不完全不同的编码,因为你现在正在做的是设置100个相同计时器的副本同时关闭。
这是一个针对其编程的不同方式的演示,它没有您的问题。
工作演示:http://jsfiddle.net/jfriend00/Zsa8m/
var games = [];
var numbers_to_letters = ["one", "two", "three", "four", "five", "six"];
function Game(){
roll_animation();
}
$("#roll_dice").click(function(){
games.push(new Game());
});
function roll_animation(){
var cntr = 0;
function next() {
var die = cntr % 6;
var nextDie = (die + 1) % 6;
$(".btn.btn-die")
.addClass(numbers_to_letters[nextDie])
.removeClass(numbers_to_letters[die]);
++cntr;
// keep going as long as cntr < 100 and we aren't on number 1
// so that the die always end on 1
if (cntr < 100 || nextDie != 0) {
setTimeout(next, 50);
}
}
next();
}
您可以明显更改常量以适合您的目的。
只是为了笑容,这是一个随机滚动而不是顺序滚动的版本:http://jsfiddle.net/jfriend00/NSW8U/