2010-04-26 7 views
2

Используя jQuery, я создаю ротатор изображений/слайдов. Основная настройка (в псевдокоде):Остановить выполнение рекурсивной функции javascript

function setupUpSlide(SlideToStartWith){ 
    var thisSlide = SlideToStartWith; 
    ...set things up... 
    fadeInSlide(thisSlide) 
} 

function fadeInSlide(thisSlide){ 
    ...fade in this slide... 
    fadeOutSlide(thisSlide) 
} 


function fadeOutSlide(thisSlide){ 
    ...fade out this slide... 
    thisSlide.fadeOut(fade, function() { 
    var timeout2 = setTimeout(setupUpSlide(nextSlide),100); 
    } 

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

Это работает просто отлично.

Теперь я хочу, чтобы кто-то перестал показывать слайд-шоу, нажав на определенный номер слайда. Поэтому, если отображается слайд # 8, и я нажимаю # 3, я хочу, чтобы рекурсия остановилась, а затем вызовите начальную функцию, проходящую в слайде # 3, которая затем, в свою очередь, снова запустит процесс.

Но я не уверен, как это сделать. Как правильно «разбить» рекурсивный скрипт. Должен ли я создать какую-то глобальную переменную «watch», которая, если в любое время будет «true», вернет: false и разрешит выполнение новой функции?

UPDATE: Добавлены более подробный код, показывающий SetTimeout вызов

ответ

7

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

Вместо этого использовать timeouts.

SetTimeout() - выполняет код, некоторое время в будущем

clearTimeout() - отменяет SetTimeout()

Или intervals:

(спасибо Ricket за указание на это!)

Метод setInterval() вызывает функцию или оценивает выражение через определенные интервалы (в миллисекундах).

Метод setInterval() будет продолжать вызов функции до вызова clearInterval() или закрытие окна.

+0

В какой-то момент, однако, мне не нужна рекурсия, чтобы продолжить цикл? То есть, если у меня 6 слайдов, мне нужно идти от 1 до 6, а затем повторять. Используя приведенные выше методы Timeout, как включить логику for-loop для увеличения количества вызовов? –

+0

@DA: Используя таймауты, вы можете создать бесконечный цикл, не получая переполнение стека. Каждый вызов представляет собой один шаг в вашем цикле. –

+0

ack. Должно было посмотреть на то, что у меня уже было ближе. Оказывается, мы используем функцию setTimeout в последней функции (которая затем, в свою очередь, вызывает первую). Я обновил образец кода в исходном сообщении. Это все, что необходимо, чтобы избежать проблемы с переполнением стека? –

0

вместо косвенной рекурсии, попробуйте использовать повторяющуюся тайм-аут (var timer_id = setInterval(...)) и использовать clearTimeout, когда вы хотите, чтобы остановить его

+0

initTimeout? вы имеете в виду setInterval? (и соответствующий clearInterval) – Ricket

+0

да, моя ошибка – matei

0

Вот простой способ сделать это. Прежде всего, вместо прямого вызова функций, используйте window.setTimeout(function(){...}) в конце каждой функции, заменив ... на последнюю строку (что делает рекурсивный вызов). Это предотвратит переполнение стека.

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

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

Смежные вопросы