Использование setTimeout func. & случайная функция анимировать элементы класса - PullRequest
0 голосов
/ 18 января 2012

Мои навыки отладки не очень помогают мне понять, что я здесь делаю неправильно.

Я хочу, чтобы каждый элемент массива анимировался по истечении заданного времени с помощью функции setTimeout.

Я не получаю никаких ошибок, и цикл, кажется, работает просто отлично, однако, ни один из элементов в массиве не в конечном итоге перемещается из своего исходного места в новое место.

function publicity()
{
// placing elements with class name 'cCameras' inside an array
var eCamerasArray = $(".cCameras").toArray();
// creating 2 arrays to hold left & top values of each element
var iLeftPosArray = [];
var iTopPosArray = [];
// loop to run through each element in array
for( var i = 0; i < eCamerasArray.length; i++)
{
    // timer variable set for each element to be used in setTimeout func.
    var timer = Math.floor (Math.random()*300) + 100;
    // setTimeout func. used to animate each element after a specified (timer) time
    window.setTimeout (function ()
    {
        iLeftPosArray[i] = Math.floor (Math.random() *139) + 360;
        iTopPosArray[i] = Math.floor (Math.random() *160) + 100 ;
        $(eCamerasArray[i]).animate ({left: iLeftPosArray[i] + "px", top: iTopPosArray[i] + "px"}, 100, "linear");
        return [iLeftPosArray[i], iTopPosArray[i]];
    }, timer);
}
}

Ответы [ 2 ]

1 голос
/ 18 января 2012

Развернув простой цикл, вы увидите, что происходит:

var i = 0;

window.setTimeout( function(){
      //No local i so it must be outside
    console.log(i);

}, 1000 );

i++;

window.setTimeout( function(){
     //No local i so it must be outside
    console.log(i);

}, 1000 );

i++;

window.setTimeout( function(){
      //No local i so it must be outside
    console.log(i);

}, 1000 );

Как видите, все функции ссылаются на один и тот же i, поэтому все они будут регистрировать 2 после срабатывания таймеров,Ни у одного из них нет локального i.

. Вы можете создать «локальный» i, например:

(function(i){
|---------^  //i found here, no need to use the global i
|   window.setTimeout( function(){
-------------------- //no local i here so it must be outside
        console.log(i);

    }, 1000 );  


})(i) //pass the "global" i as argument, with the value it has right now
1 голос
/ 18 января 2012

Вы можете исправить это, создав закрытие:

(function publicity() {
    var eCamerasArray = $(".cCameras"),
        iLeftPosArray = [],
        iTopPosArray = [],
        timer;
    for(var i = 0; i < eCamerasArray.length; i += 1) {
        timer = Math.floor (Math.random() * 300) + 100;
        (function (i) {
            window.setTimeout (function () {
                iLeftPosArray[i] = Math.floor (Math.random() * 139) + 360;
                iTopPosArray[i] = Math.floor (Math.random() * 160) + 100 ;
                $(eCamerasArray[i]).animate ({left: iLeftPosArray[i] + "px", top: iTopPosArray[i] + "px"}, 300, "linear");
                return [iLeftPosArray[i], iTopPosArray[i]];
            }, timer);
        }(i));
    }
}());

Вы можете увидеть эффект здесь: http://jsfiddle.net/zHUAt/2/

С наилучшими пожеланиями!

...