我有一个冒泡排序功能,当交换发生时,它应该显示它。但经过多次处理后,它继续执行循环而不等待动画停止。 (我们只允许使用JavaScript)。有没有办法告诉网站等待动画完成。以下是我的代码片段:
for (var i = 0; i < len; i++)
{
for (var j = 0, swapping, endIndex = len - i; j < endIndex; j++)
{
if (marksArr[j] > marksArr[j + 1])
{
//swap objects
/*(function() {
var k = 0,
action = function() {
document.getElementById(coursesKey[j]).style.top = (parseInt(document.getElementById(coursesKey[j]).style.top) + 1) + 'px';
document.getElementById(coursesKey[j + 1]).style.top = (parseInt(document.getElementById(coursesKey[j+1]).style.top) - 1) + 'px';
k++;
if (k < difMoves) {
setTimeout(action, 200);
}
};
setTimeout(action, 200);
})();*/
}
}
}
答案 0 :(得分:0)
正如@cookie怪物已经解释的那样,你不能在JavaScript中阻止循环并同时使用setTimeout()
更新UI(这是因为JavaScript本质上是单线程的)。
最优雅的解决方案是“记录”每个动画步骤,同时for
循环处理数组,然后运行动画,例如使用setTimeout()
。前段时间,I've implemented this approach在StackOverflow上提出了类似的问题;这是一个演示:JSFiddle
代码也可以简化:
function swap(list, i1, i2) {
var tmp = list[i1];
list[i1] = list[i2];
list[i2] = tmp;
}
function animateBubblesort(list) {
var animationSteps = [];
// Sort array
for (var n = list.length; n > 1; --n) {
for (var i = 0; i < n-1; ++i) {
if (list[i] > list[i+1]) {
swap(list, i, i+1);
// Add new step (clone of current array) to "animation queue"
animationSteps.push(list.slice(0));
}
}
}
// Print animated steps (using setInterval() for simplicity)
var count = 0,
interval = setInterval(function(){
console.log(animationSteps[count]);
if (++count >= animationSteps.length) {
clearInterval(interval);
}
}, 250);
}
animateBubblesort([5,8,2,4,1,9,7,3,0,6]);
另一种(不太直观)的可能性是在没有循环的情况下实现算法,以便在执行算法的下一步时控制(因此您有时间动画)。这是一个例子:DEMO 2