Отменить синхронизированный цикл в JavaScript? - PullRequest
0 голосов
/ 28 октября 2009

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

//I know this is ugly, I'm just learning JavaScript again and plan to recode it after I learn some more...
var fadeOut = false

//set out to true to fade out, false to fade in
function fade(out) {
    var steps = 1
    var outSpeed = 100
    var inSpeed = 10
    var timer = 0

    if (out) {
            //fade out
            fadeOut = true
            for ( var i=100; i>=0; i-=steps ) {
                    if ( fadeOut ) {
                            setTimeout("set_el_opacity(" + (i / 100) + ")",
                            timer+=steps
                    } else {
                            break;
                    }
            }
    } else {
            //fade in
            fadeOut = false
            for ( var i=0; i<=100; i+=steps ) {
                    if( !fadeOut ) {
                            setTimeout("set_el_opacity(" + (i / 100) + ")",
                            timer+=steps
                    } else {
                            break;
                    }
            }
    }
}

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

fade (true) работает нормально, fade (false) работает отлично и работает быстрее. Моя проблема возникает, когда я вызываю fade (true), за которым вскоре следует fade (false). Фейды борются друг с другом, а затем, поскольку вызов fade (true) выполняется быстрее, он сначала завершается, а вызов fade (false) продолжает полностью исчезать.

Мой вопрос: что я могу сделать, чтобы вызов fade (false) отменил цикл вызова fade (true)?

Ответы [ 4 ]

7 голосов
/ 28 октября 2009

При установке таймера:

mytime = setTimeout('function()', 1000);

вы можете отменить его, используя clearTimeout:

clearTimeout(mytime);
0 голосов
/ 26 апреля 2017

ПРОСТОЙ СПОСОБ ОБРАЩАТЬСЯ К ПЕРИОДУ ВРЕМЕНИ

function myFunc (terminator = false) {
    if(terminator) {
        clearTimeout(timeOutVar);
    } else {
        // do something
        console.log("loop");
        timeOutVar = setTimeout(function(){myFunc();}, 1000);
    }
}   
myFunc(true); //  -> start loop
myFunc(false); //  -> end loop
0 голосов
/ 28 октября 2009

Начнем с того, что не стоит запускать много таймеров в цикле. Вместо этого вы должны использовать setInterval или запустить новый таймер из вашего обработчика setTimeout.

Другой подход заключается в том, чтобы иметь один таймер, который срабатывает через фиксированные интервалы и управляет всеми ожидающими эффектами. Вы можете выбрать частоту кадров и позволить своему таймеру («стеку таймеров») работать бесконечно, «тикая» на каждом кадре - вы можете при желании запускать / останавливать тиканье, когда нет ожидающих эффектов.

0 голосов
/ 28 октября 2009

Вы должны отменить активный тайм-аут при каждом вызове fade(), используя функцию clearTimeout(). Для получения дополнительной информации о тайм-аутах, ознакомьтесь с этой статьей . Вот краткий пример на основе предоставленного вами кода.

var timeoutId = null;

function fade(out) {
    // ...
    // Your variable declarations
    // ...

    // Cancel the active timeout, if any.
    clearTimeout(timeoutId);

    // Record the timeout ID inside your if-else blocks
    if (out) {
        // ...
        timeoutId = setTimeout( ... );
        // ...
    } else {
        // ...
        timeoutId = setTimeout( ... );
        // ...
    }
}
...