Javascript在显示元素时循环显示数组

时间:2020-12-05 21:21:49

I want to create a 'random selector' behaviour where the function iterates through an array for a period of time (example: 3 seconds, 5 seconds) while displaying all of array elements fast throughout the iteration until the iteration ends. Just imagine seeing all the elements displayed in a label one after another until it finally stops at an element.

我想创建一个'随机选择器'行为,其中函数迭代一个数组一段时间(例如:3秒,5秒),同时在整个迭代过程中快速显示所有数组元素,直到迭代结束。想象一下,看到标签中的所有元素一个接一个地显示,直到它最终停在一个元素上。

My code so far:

我的代码到目前为止:

var places = ["Curry Leaf", "Subway", "Burger King"];

function execute_randomizer() {
    var place_label = document.getElementById("place_label");
    for (var i = 0; i < 100; i++) {
        var selected_place = places[Math.floor(Math.random() * places.length)];
        setTimeout(function () {
            place_label.innerText = selected_place;
        }, 400);
    }
}

This runs through the iteration and displays an element when the loop is done but it doesn't show each iteration's element. How can I amend this?

这将贯穿迭代并在循环完成时显示一个元素但不显示每个迭代的元素。我该如何修改?

EDIT

Even if there's 3 elements, the animations must re-iterate through the array until the duration is completed

即使有3个元素,动画也必须重新遍历数组,直到持续时间结束

4 个解决方案

#1


1  

Your for finishes iterating before the setTimeout runs, then the function passed to setTimeout runs 100 times using the last value of selected_place.

您在setTimeout运行之前完成迭代,然后传递给setTimeout的函数使用selected_place的最后一个值运行100次。

More about this behavior in setTimeout in for-loop does not print consecutive values

有关for循环中setTimeout中此行为的更多信息不会打印连续值


Another problem that I noticed is that your setTimeout will trigger after 400ms, since the for loop will finish in about 1 ms, the function passed to setTimeout will trigger 100 times one after another with no delay in between, for this, I replaced the delay argument of setTimeout from 400 to 400 * i.

我注意到的另一个问题是你的setTimeout将在400ms后触发,因为for循环将在大约1ms内完成,传递给setTimeout的函数将一个接一个地触发100次,两者之间没有延迟,为此,我替换了延迟setTimeout的参数从400到400 * i。


var places = ["Curry Leaf", "Subway", "Burger King"];     
function execute_randomizer() {
    var place_label = document.getElementById("place_label");
    for (var i = 0; i < 100; i++) {
        var selected_place = places[Math.floor(Math.random() * places.length)];
        (function(selected_place){
          setTimeout(function () {
              place_label.innerText = selected_place;
          }, 400 * i);
        })(selected_place);
    }
}
execute_randomizer();
<span id="place_label"></span>

#2


1  

You could use a closure over the value and a different time for each timeout.

您可以对值使用闭包,并为每个超时使用不同的时间。

var places = ["Curry Leaf", "Subway", "Burger King"];

function execute_randomizer() {
    var place_label = document.getElementById("place_label");
    for (var i = 0; i < 10; i++) {
        var selected_place = places[Math.floor(Math.random() * places.length)];
        setTimeout(function (value) {
            return function () {
                place_label.innerText = value;
            };
        }(selected_place), i * 100);
    }
}

execute_randomizer();
<div id="place_label"></div>

For a first run through, you could show each element and then take a random element at last value.

对于第一次运行,您可以显示每个元素,然后在最后一个值处获取随机元素。

function execute_randomizer() {
    function cb (value) {
        return function () {
            place_label.innerText = value;
        };
    }

    var place_label = document.getElementById("place_label");

    place_label.innerText = '';
    for (var i = 0; i < places.length; i++) {
        setTimeout(cb(places[i]), 200 + i * 200);
    }
    setTimeout(cb(places[Math.floor(Math.random() * places.length)]), 200 + places.length * 200);
}

var places = ["Curry Leaf", "Subway", "Burger King"];

execute_randomizer();
<div id="place_label"></div>

#3


0  

You should change your loop because right now you go in loop 100 times in maybe one millisecond and order 100 of change text but once again in the same time. So better is wait for time out 400 ms and then make next iteration. Please remember time out is async.

你应该改变你的循环,因为你现在循环100次,可能是一毫秒,并且在同一时间再次订购100个更改文本。所以更好的是等待超过400毫秒的时间,然后进行下一次迭代。请记住超时是异步的。

#4


0  

I think it might be better if you would put the whole function in a timeout. (I'm not sure and didn't test, but that's what I would try).

我认为如果将整个函数置于超时状态可能会更好。 (我不确定也没有测试,但这就是我要尝试的)。

What I mean is that you just build a function that creates your randomizer and fills in your field. After that you put a timeout to call the same function again + keep a counter that you pass as parameter.

我的意思是你只需要构建一个函数来创建随机函数并填充你的字段。之后你再次调用相同的函数超时+保留一个你作为参数传递的计数器。

An example of what I mean below: (didn't test it)

我在下面的意思的一个例子:(没有测试它)

var places = ["Curry Leaf", "Subway", "Burger King"];

execute_randomizer(0); /* Start for the first time */

function execute_randomizer(times) {
    if(times == 100)
        return; /* stop execution */

    var place_label = document.getElementById("place_label");
    var selected_place = places[Math.floor(Math.random() * places.length)];
    place_label.innerText = selected_place;
    setTimeout(function () {
        execute_randomizer(times+1)
    }, 400);
}

#1


1  

Your for finishes iterating before the setTimeout runs, then the function passed to setTimeout runs 100 times using the last value of selected_place.

您在setTimeout运行之前完成迭代,然后传递给setTimeout的函数使用selected_place的最后一个值运行100次。

More about this behavior in setTimeout in for-loop does not print consecutive values

有关for循环中setTimeout中此行为的更多信息不会打印连续值


Another problem that I noticed is that your setTimeout will trigger after 400ms, since the for loop will finish in about 1 ms, the function passed to setTimeout will trigger 100 times one after another with no delay in between, for this, I replaced the delay argument of setTimeout from 400 to 400 * i.

我注意到的另一个问题是你的setTimeout将在400ms后触发,因为for循环将在大约1ms内完成,传递给setTimeout的函数将一个接一个地触发100次,两者之间没有延迟,为此,我替换了延迟setTimeout的参数从400到400 * i。


var places = ["Curry Leaf", "Subway", "Burger King"];     
function execute_randomizer() {
    var place_label = document.getElementById("place_label");
    for (var i = 0; i < 100; i++) {
        var selected_place = places[Math.floor(Math.random() * places.length)];
        (function(selected_place){
          setTimeout(function () {
              place_label.innerText = selected_place;
          }, 400 * i);
        })(selected_place);
    }
}
execute_randomizer();
<span id="place_label"></span>

#2


1  

You could use a closure over the value and a different time for each timeout.

您可以对值使用闭包,并为每个超时使用不同的时间。

var places = ["Curry Leaf", "Subway", "Burger King"];

function execute_randomizer() {
    var place_label = document.getElementById("place_label");
    for (var i = 0; i < 10; i++) {
        var selected_place = places[Math.floor(Math.random() * places.length)];
        setTimeout(function (value) {
            return function () {
                place_label.innerText = value;
            };
        }(selected_place), i * 100);
    }
}

execute_randomizer();
<div id="place_label"></div>

For a first run through, you could show each element and then take a random element at last value.

对于第一次运行,您可以显示每个元素,然后在最后一个值处获取随机元素。

function execute_randomizer() {
    function cb (value) {
        return function () {
            place_label.innerText = value;
        };
    }

    var place_label = document.getElementById("place_label");

    place_label.innerText = '';
    for (var i = 0; i < places.length; i++) {
        setTimeout(cb(places[i]), 200 + i * 200);
    }
    setTimeout(cb(places[Math.floor(Math.random() * places.length)]), 200 + places.length * 200);
}

var places = ["Curry Leaf", "Subway", "Burger King"];

execute_randomizer();
<div id="place_label"></div>

#3


0  

You should change your loop because right now you go in loop 100 times in maybe one millisecond and order 100 of change text but once again in the same time. So better is wait for time out 400 ms and then make next iteration. Please remember time out is async.

你应该改变你的循环,因为你现在循环100次,可能是一毫秒,并且在同一时间再次订购100个更改文本。所以更好的是等待超过400毫秒的时间,然后进行下一次迭代。请记住超时是异步的。

#4


0  

I think it might be better if you would put the whole function in a timeout. (I'm not sure and didn't test, but that's what I would try).

我认为如果将整个函数置于超时状态可能会更好。 (我不确定也没有测试,但这就是我要尝试的)。

What I mean is that you just build a function that creates your randomizer and fills in your field. After that you put a timeout to call the same function again + keep a counter that you pass as parameter.

我的意思是你只需要构建一个函数来创建随机函数并填充你的字段。之后你再次调用相同的函数超时+保留一个你作为参数传递的计数器。

An example of what I mean below: (didn't test it)

我在下面的意思的一个例子:(没有测试它)

var places = ["Curry Leaf", "Subway", "Burger King"];

execute_randomizer(0); /* Start for the first time */

function execute_randomizer(times) {
    if(times == 100)
        return; /* stop execution */

    var place_label = document.getElementById("place_label");
    var selected_place = places[Math.floor(Math.random() * places.length)];
    place_label.innerText = selected_place;
    setTimeout(function () {
        execute_randomizer(times+1)
    }, 400);
}