我是javascript的新手。我正在进行可视化排序,我想逐个更改数组元素的颜色。我试着这么做,但它们同时都变了布局
function selectionSort(main_arr)
{
var arr_slots = document.getElementById("draw-area").childNodes;
for (var i=0; i<main_arr.length; i++)
{
arr_slots[i].style.backgroundColor="red";
(function(index)
{
setTimeout(function()
{
arr_slots[index].style.backgroundColor="#f2f2f2";
},1000);
})(i)
}
}
对于循环中的所有项目,您的setTimeout设置为1秒后熄灭。这不是累积的,所以基本上循环会很快完成(从你的角度来看几乎是即时的(;i〃;setTimeouts的数量,所有这些都在一秒钟后触发。
您需要使用";i〃;将计时器设置为递增到您需要的任何时间(此外,您不需要将setTimeout封装在一个匿名的自执行函数中
function selectionSort(main_arr) {
var arr_slots = document.getElementById("draw-area").childNodes;
for (var i=0; i < main_arr.length; i++) {
arr_slots[i].style.backgroundColor="red";
setTimeout(function() {
arr_slots[index].style.backgroundColor="#f2f2f2";
}, i * 1000);
}
}
这将使每个计时器从0秒开始一秒接一秒地启动。可以通过几种方式调整时间
i * 100 // every tenth of a second
(i * 100) + 2000 // every tenth of a second starting after 2 seconds
你也可以添加宽松,但我不会在这里讨论(主要是因为我无法从头开始(
这种类型的事情通常可以很好地使用css来处理,或者如果你研究像animejs这样的库,它可以很容易地对元素进行惊人的更改。
还可以查看document.querySelectorAll,这样您就可以像一样使用它
var array_slots = document.querySelectorAll("#draw-area > *");
// or whatever the css selector is
array_slots.forEach(function(element) {
// element returns the html element in the array_slots list
// do whatever code you need here
});
希望能有所帮助。
setTimeout开始一个异步进程,等待,然后触发回调。您的循环几乎立即遍历所有元素。您需要重新编写代码,以便上一次颜色更改触发下一个元素的颜色更改计时器。
出了什么问题
您的for循环同时设置所有的setTimeout
。因此,所有超时都在同一时间执行。
相反该怎么办:
1.使用递归
const messages = [
'Message #1',
'Message #2',
'Message #3',
];
showMessages(messages, 0)
function showMessages( messages, index ) {
// don't run when the index cannot select a message, because it is done iterating over the array
if( messages.length === index) return;
console.log( messages[index] );
index = index += 1;
window.setTimeout( () => {
showMessages( messages, index );
}, 1000);
}
2.使用索引计算不同的超时
const messages = [
'Message #1',
'Message #2',
'Message #3',
];
for(let index=0; index<messages.length; index++) {
window.setTimeout( () => {
console.log( messages[index] );
}, 1000*index);
}
可能还有更多的方法,但这些似乎是最基本的。