почему цикл setInterval() с каждым разом проходит быстрее?

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

Мой код:

$(document).ready(function () {
    var ciclo;
    var index_slide = 1;

    function startSlidercicle() {
        ciclo = setInterval( function() {
            // Slider code goes here
        }, 3000); 
    }

    //Here I start the slider animation
    startSlidercicle();

    //When the user clicks on a div called 'slide', stop the cycle and start again the animation cycle
    $('.slide').on('click', function() {
        clearInterval(ciclo);
        setTimeout(startSlidercicle(), 3000);
    });
});

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


person Community    schedule 22.08.2013    source источник
comment
Вы должны использовать setTimeout(startSlidercicle, 3000) (без скобок после startSlidercicle). Но это не должно быть причиной того, что вы описываете...   -  person bfavaretto    schedule 23.08.2013
comment
Я могу воспроизвести это, только если несколько раз щелкну div .slide (см. jsfiddle.net/XdMHz). Вы должны добавить защиту от этого, потому что это создает оставшиеся таймеры, на которые вы не можете ссылаться / очищать.   -  person bfavaretto    schedule 23.08.2013
comment
Я прочитал несколько вопросов по одной и той же теме, но не знаю, как предотвратить или закрыть эти несколько таймеров.   -  person    schedule 23.08.2013
comment
Один из способов, которым вы можете предотвратить несколько таймеров, в основном такой же, как вы в настоящее время очищаете свой интервал: создайте новую переменную timerId (или как вы хотите ее назвать), затем в своем обработчике кликов добавьте clearTimeout(timerId), а затем timerId = setTimeout(....   -  person nnnnnn    schedule 23.08.2013
comment
В отсутствующем коде ползунка нет другого setTimeout или setInterval? Кажется, не могу воссоздать проблему с тем, что у вас здесь.   -  person Jesse Kernaghan    schedule 23.08.2013


Ответы (2)


Вместо:

clearInterval(ciclo);
setTimeout(startSlidercicle(), 3000);

or:

clearInterval(ciclo);
setTimeout(startSlidercicle, 3000);

Я изменил код на:

clearInterval(ciclo);
startSlidercicle();

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

person Community    schedule 22.08.2013
comment
Уже протестировано с Firefox 23, IE 9, Opera 12+ и Chrome 29 в Windows 7 и все еще работает нормально. - person ; 23.08.2013
comment
Мой вывод состоит в том, что clearInterval(ciclo) завершает цикл setInterval внутри startSlidercicle(), поэтому внутри функции не остается кода, и она выходит, затем переходит к следующей строке, где я вызываю новую startSlidercicle(), и если я нажимаю много раз, я просто заканчиваю и запуск новых setInterval методов - person ; 23.08.2013

Вам нужно изменить это:

clearInterval(ciclo);
setTimeout(startSlidercicle(), 3000);

к этому:

clearInterval(ciclo);
setTimeout(startSlidercicle, 3000);

В вашем существующем коде вы вызываете startSlidercirle немедленно, и он не ждет, пока сработает setTimeout(), потому что у вас есть () после имени функции. Это означает выполнить его немедленно и передать результат выполнения в setTimeout(). Вы хотите просто передать ссылку на функцию в setTimeout(), что делается с помощью простого имени функции без () после него. Это распространенная ошибка.

person jfriend00    schedule 22.08.2013