0

在以下示例中,此脚本以稳定的速率随机地将“green”类应用于所有“span”HTML 元素。

var items = $('span').get();
var interval = setInterval(function() {
    var random_number = Math.floor(Math.random() * items.length);
    $(items[random_number]).addClass('green');
    items.splice(random_number, 1);
    if (items.length === 0) {
        clearInterval(interval);
      }
     }, 10);

http://jsfiddle.net/DUbQB/

我已经对其进行了更新,使其每个间隔更改 2 个元素,只需调用该函数两次即可。

var items = $('span').get();
var interval = setInterval(function() {

    function rand(random_number) {
    var random_number = Math.floor(Math.random() * items.length);
    $(items[random_number]).addClass('green');
    items.splice(random_number, 1);
    }

    rand(1);
    rand(2);

    if (items.length === 0) {
        clearInterval(interval);
    }
}, 500);

http://jsfiddle.net/DUbQB/3/

我只想知道,有没有办法让这个脚本同时随机将所有元素变为绿色而不管有多少元素?

例如,http://jsfiddle.net/DUbQB/3/以十个间隔完成,因为有二十个元素并且随机函数被调用了两次。

但如果有 40 个元素,脚本将需要 20 个间隔,因此长度会增加一倍。不管有多少元素,这个脚本怎么能总是花费相同的时间来完成?

4

4 回答 4

2

我不是 JS 开发人员,但这吸引了我尝试(我第一次尝试 JSFiddle,它真的很酷)。

这是一个解决方案,即使存在舍入差异,也会产生恒定的步数。

function DoTransition() {
    var items = $('span').get();
    var steps = 10;
    var residuum = 0;
    var interval = setInterval(function() {

        function rand() {
            var random_number = Math.floor(Math.random() * items.length);
            $(items[random_number]).addClass('green');
            items.splice(random_number, 1);
        }

        var localSteps = items.length / steps + residuum;
        residuum = localSteps - Math.round(localSteps);
        localSteps = Math.round(localSteps);
        for (var i = 0; i < localSteps; i++) {
            rand();
        }

        steps--;

        if (items.length === 0) {
            clearInterval(interval);
        }
    }, 500);
}

DoTransition();

更新:修复了少量项目的问题......只是缺少对 Math.round 的调用。现在有中间步骤,如果需要,更新了 0 个项目。为了测试,我创建了一个新版本,它使用 localSteps 变量 ( http://jsfiddle.net/vQDhf/ ) 更新星号。

UPDATE2:现在是一个数学上正确的过渡,在时间线上平均分布。

于 2013-02-18T08:19:27.887 回答
1

您只需进行少量数学计算即可确定运行区间的速度或每个区间要更改的元素数量。

例如,如果您希望它在 5000 毫秒内完成,那么您只需执行以下操作:

var items = $('span').get();
var intervalTime = 5000 / items.length;

然后intervalTimesetInterval()通话中使用它。无论有多少跨度,这将在 5000 毫秒内完成操作。

于 2013-02-18T08:09:07.573 回答
1

“以相同的速率”是指每间隔数的操作数相同。换句话说,您当前正在执行的操作(2 elem/interval)是一个恒定速率。相反,您要求的是相同数量的间隔。这也是可行的,但请注意,它需要预定义数量的间隔,并且会根据元素的数量改变速率。

var numIntervals = SOME_PREDEFINED_VALUE; // e.g. always use 4 intervals
var items = $('span').get();

var elemsPerInterval = Math.floor(items.length/numIntervals);
var extraElems = elemsPerInterval * numIntervals;

var interval = setInterval(function() {

    function rand() {
        var random_number = Math.floor(Math.random() * items.length);
        $(items[random_number]).addClass('green');
        items.splice(random_number, 1);
    }

    // do one extra element per iteration to account
    // for residuals due to rounding
    int j = extraElems-- > 0 ? -1 : 0;

    while ( j < elemsPerInterval ) {
        rand();
        j++;
    }

    if (items.length === 0) {
        clearInterval(interval);
    }
}, 500);
于 2013-02-18T08:10:12.293 回答
0

http://jsfiddle.net/CA97a/

谢谢@JWH 给它一个计时器http://jsfiddle.net/CA97a/5/

我认为更改计时器间隔会更简单

<div class="container">
</div>

<script>
// Use for test
for (var i=0; i < 20 /*Count*/; i++) {
    $(".container").append("<span> "+i+" </span>");
}

// Script start
var items = $('span').get();
var interval = setInterval(function() {
    var random_number = Math.floor(Math.random() * items.length);
    $(items[random_number]).addClass('green');
    items.splice(random_number, 1);

    if (items.length <= 0) {
        clearInterval(interval);
    }
}, 5000/items.length); // Finish in 5 sec
</script>

我还有一个想法,这样时间会更准确,我在火狐10K测试过,不觉得太卡 http://jsfiddle.net/LmE6J/

$("span").each(function () {
    function closure(s) {
        return function () {
            $(s).addClass("green");
        };
    }
    setTimeout(closure(this), (Math.random()*Math.floor(5000)));
});
于 2013-02-18T09:31:50.837 回答