Отмена / остановка выполнения функции обратного вызова в jQuery / Javascript - PullRequest
1 голос
/ 12 октября 2011

У меня есть анимация, которая настроена на воспроизведение после тайм-аута. Эта анимация повторяется на разных элементах после завершения. Я использую функцию обратного вызова метода animate для запуска следующей анимации. Мой извлеченный код выглядит так:

function fancyAnimation() {
    // Get a random object property, which is actually the id for a dot
    var id = getRandomNumber( 1, 100 );

    // Apply an effect to the dot
    $( '#test' + id ).effect(
        'pulsate',
        { times : 3 },
        1000,
        fancyAnimation
    );
}

На событии щелчка я хочу, чтобы анимация остановилась. В любой момент времени функция "fancyAnimation" ставится в очередь для запуска, которая просто ставит ее в очередь снова и снова и т. Д.

Есть ли способ, которым я могу остановить выполнение этой функции, тем самым завершив бесконечный цикл для определенного события? Если так, как бы вы это сделали?

Большое спасибо!

РЕДАКТИРОВАТЬ: По запросу код, который инициирует fancyAnimation.

function initiateFancyAnimation() {
    animation_timeout = setTimeout( "fancyAnimation()", animation_interval );
}

Ответы [ 3 ]

2 голосов
/ 12 октября 2011

Что ж, проще всего было бы установить глобальный флаг, который вы проверяете при каждом запуске функции:

var runAnimation;

function fancyAnimation() {
    if (runAnimation) {
        // your function body as written
    }
}

$('#start').click(function() {
    runAnimation = true;
    fancyAnimation();
});

$('#stop').click(function() {
    runAnimation = false;
});
0 голосов
/ 07 августа 2014

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

$('#start').click(function(){  
    // open event bus
    var eventBus = new Bacon.Bus();

    // tell eventBus to run animation every time it receives event
    eventBus.onValue(function(){
        fancyAnimation();
    });

    // push initial event to start animation immediately
    eventBus.push();

    // continue to push events at interval
    eventBus.plug(Bacon.fromPoll(animation_interval, function(){
        return new Bacon.Next();
    }));

    $("#start").attr("disabled", "disabled");
    $("#stop").removeAttr("disabled"); 

    // tell eventBus to end when stop is clicked
    $('#stop').click(function(){
        eventBus.end();

        $("#stop").attr("disabled", "disabled");
        $("#start").removeAttr("disabled");   
    });
});

Рабочая демонстрация на http://jsfiddle.net/ronaldchanou/o4hk0176/2/

0 голосов
/ 12 октября 2011

Вы можете применить определенный класс к «точке», когда пользователь щелкает элемент, а затем проверять этот класс в каждом цикле следующим образом:

$('#button').click(function(){
    $('#targetDot').addClass('stop');
});

function fancyAnimation() {    
// Get a random object property, which is actually the id for a dot
    var id = getRandomNumber( 1, 100 );

    // Check for Class and Execute ONLY is .stop is not found //
    if ($(id).hasClass('stop') !== true ){
        // Apply an effect to the dot
        $( '#test' + id ).effect(
            'pulsate',
            { times : 3 },
            1000,
            fancyAnimation
        );
    }
}

ПРАВКА:

альтернативой, которую я использовал в прошлом, является плагин $. doTimeout , который позволяет контролировать обратный вызов немного лучше.

$.doTimeout('timeoutID', 3000, function() {
    // Check for Global Run True / False Flag //
    if (runAnimation){
        fancyAnimation();
    }
});

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

...