Немедленно остановить цикл setTimeout без завершения текущего цикла

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

Затем на странице поочередно будут выделены два случайных результата - пользователь может снова нажать кнопку и выбрать желаемое видео.

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

как бы я получить так, чтобы, когда пользователь нажимал кнопку "выбор", функция flit немедленно прекращалась, а не по окончании текущего цикла?

Вот скрипка

http://jsfiddle.net/zandergrin/tmwst5z9/4/

ps - извиняюсь, но это проделанная работа - я знаю, что здесь есть несколько неприятных моментов... var interval = 0;

function random() {
    // create the array
    var posts = ["post 1", "post 2", "post 3", "post 4", "post 5", "post 6", "post 7", "post 8", "post 9", "post 10"];
    var results = posts

    // Shuffle array
    .sort(function () {
        return .5 - Math.random()
    })

    // Get first 2 items
    .slice(0, 2);
    var post1 = results[0];
    var post2 = results[1];

    // add them to the DOM
    $('#res1').html(post1);
    $('#res2').html(post2);

    // loop it
    interval = setTimeout(random, 100);

}

function start() {
    // Hide the start button
    $("#start").css("display", "none");
    $("#stop").css("display", "block");
    // Start the randomizer
    random();

}


function stop() {
    // Hide the stop button and stop the random() timeout
    clearTimeout(interval);
    $("#stop").css("display", "none");
    $("#select").css("display", "block");

    // set the inital background colour
    $("#res1").css({'background': '#123','color': '#fff'});
    $("#res2").css({'background': '#eee','color': '#000'});

    //create a function to flick between items
    function flit() {
        //color the results
        setTimeout(function () {
            $("#res1").css({'background': '#eee','color': '#000'});
            $("#res2").css({'background': '#123','color': '#fff'});
        }, 800);

        //colour again after a delay
        setTimeout(function () {
            $("#res1").css({'background': '#123','color': '#fff'});
            $("#res2").css({'background': '#eee','color': '#000'});
        }, 1600);

        //loop it
        timer = setTimeout(arguments.callee, 1600);
    };
    //run the flick function
    flit();

}


function select() {
    // stop thie flit function - doesnt stop immediately!
    clearTimeout(timer);
    $("#select").css("display","none");
    $("#refresh").css("display", "block");
}

function refresh() {
    location.reload();
}

2 ответа

Решение

Ваша проблема в flit() функция - вам нужно назначить ссылки на setTimeout звонки, чтобы вы могли позвонить clearTimeout на них. Прямо сейчас вы останавливаетесь flit() от вызова в select() метод, но два таймера все еще стоят в очереди для выполнения в будущем.

В дополнение к ответу @sholanozie, я бы порекомендовал поместить эти setTimeout в массив (т.е. arrayOfTimeouts), а потом:

function select() {
    // stop thie flit function - doesnt stop immediately!
    arrayOfTimeouts.forEach(function(setTimer) {
        clearTimeout(setTimer);
});
Другие вопросы по тегам