无论有多少元素,此脚本如何将类应用于所有指定的HTML元素?

时间:2013-02-18 08:00:55

标签: jquery

在下面的示例中,此脚本将随机且以稳定的速率将“绿色”类应用于所有“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/以十个间隔完成,因为有二十个元素,随机函数被调用两次。

但是如果有四十个元素,则脚本需要20个间隔,因此需要两倍的时间。无论有多少元素,这个脚本如何总是花费相同的时间来完成?

4 个答案:

答案 0 :(得分: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:现在是一个数学上正确的过渡,在时间线上平均分配。

答案 1 :(得分:1)

您只需要进行小型数学计算,以确定运行间隔的速度或每个间隔要更改的元素数量。

例如,如果您希望它在5000毫秒内完成,那么您只需:

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

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

答案 2 :(得分: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);

答案 3 :(得分: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>

我还有另外一个想法,这种方式时间会更准确,我在Firefox中用10K测试它,不要觉得太多滞后 http://jsfiddle.net/LmE6J/

$("span").each(function () {
    function closure(s) {
        return function () {
            $(s).addClass("green");
        };
    }
    setTimeout(closure(this), (Math.random()*Math.floor(5000)));
});