Использование setTimeout для задержки анимации jQuery

Я работаю над некоторыми переходами на изображение, когда пользователь нажимает кнопку, чтобы перейти к следующему изображению. Когда есть несколько изображений рядом друг с другом, которые очень узкие, все эти изображения будут переходить в одно и то же время. Поэтому я проверяю ширину изображений и добавляю тонкие в массив, а затем запускаю переход для каждого объекта в массиве. Я хотел создать небольшую задержку между анимацией каждого изображения в массиве, поэтому я пытаюсь запустить свой jQuery.animate после тайм-аута в 1 секунду.

Вот способы, которыми я безуспешно пытался заставить тайм-аут работать:

1.

for (i=0; i < set.length; i++) {
    if (i != 0) {
        setTimeout(function() { set[i].transitionOut($('#gallery'), 562) }, 100);
    } else {
        set[i].transitionOut( $('#gallery'), 562 );
    }
}

2.

for (i=0; i < set.length; i++) {
    if (i != 0) {
        function tempTransition() {
            set[i].transitionOut( $('#gallery'), 562 );
        }
        setTimeout(tempTransition, 100);
    } else {
        set[i].transitionOut( $('#gallery'), 562 );
    }
}

3.

for (i=0; i < set.length; i++) {
    if (i != 0) {
        setTimeout('function() { set[i].transitionOut($("#gallery"), 562) }', 100);
    } else {
        set[i].transitionOut( $('#gallery'), 562 );
    }
}

переходВыход():

jQuery.fn.transitionOut = function(parent, height) {
    this.animate({
        height: '0',
        top: height + 'px'
    }, function() {
        $(this).remove();
    });
}

Я заработал, используя пример закрытия CMS. Но теперь я столкнулся с новой проблемой. Переход происходит только со вторым изображением. Когда есть три изображения, он будет анимировать изображение 1, задерживать, анимировать изображение 2, анимировать изображение 3. Между 2 и 3 задержки нет.

Вот новый код:

for (i=0; i < set.length; i++) {
    (function(i) {
        if (i != 0) {

            function tempTransition() {
                set[i].transitionOut( $('#gallery'), 562 );
            }
            setTimeout(tempTransition, 200);
        } else {
            set[i].transitionOut( $('#gallery'), 562 );
        }
    })(i);
}

person Community    schedule 30.11.2009    source источник
comment
Что такое функция transitionOut? Можете ли вы предоставить этот код?   -  person Doug Neiner    schedule 30.11.2009
comment
Конечно. Я добавил это к своему исходному вопросу.   -  person    schedule 30.11.2009


Ответы (3)


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

Переменная i, на которую ссылается ваша функция обратного вызова setTimeout, та же самая (поскольку JavaScript имеет только область действия, а не область действия блока), и к моменту выполнения этих функций асинхронно цикл уже завершен, и переменная i будет содержать set.length - 1 для всех случаев, когда используется setTimeout.

Как обычно, попробуйте захватить переменную i, используя другое замыкание:

for (var i=0; i < set.length; i++) {
  (function (i) {
    if (i != 0) {
        setTimeout(function() { set[i].transitionOut($('#gallery'), 562) }, 100);
    } else {
        set[i].transitionOut( $('#gallery'), 562 );
    }
  })(i);
}
person Christian C. Salvadó    schedule 30.11.2009
comment
Благодарить. Это помогло мне преодолеть первое препятствие. :) - person ; 30.11.2009

Использование тайм-аута — хитрая штука, когда дело доходит до синхронизированной анимации/эффекта.

Я не проверял ваш код, но, просматривая его, я заметил, что вы используете setTimeout без каких-либо средств для их очистки.

Что происходит, когда пользователи инициируют события во время «задержки»? Вы должны реализовать что-то, чтобы управлять этим.

Извините, у меня нет ответа для вас сейчас, возможно, когда у меня будет больше времени позже или кто-то предложит более элегантное решение.

person o.k.w    schedule 30.11.2009

jquery fadeOut http://docs.jquery.com/Effects/fadeOut позволяет создать обратный вызов , функцию, которую вы можете запустить, когда затухание завершится. Поэтому, если вы хотите, вы можете связать переходы вместе, чтобы, когда один из них заканчивался, он вызывал следующий. Если это не то, что вы ищете, я могу неправильно понять ваш вопрос.

Кроме того, в примере 3, я думаю, вы хотите написать это так и не передавать определение функции в setTimeout, поскольку это ничего не сделает.

setTimeout('set[i].transitionOut($("#gallery"), 562)', 100);
person Jarrett Widman    schedule 30.11.2009