Я пытаюсь построить carousel
, который:
- Имеет автоспуск (каждые X секунд)
- Имеет стрелки направления (которые при использовании должны сбрасыватьсяавтоматический таймер на X секунд снова)
У меня было это с помощью функции setInterval, но проблема была еще хуже, поэтому я решил изменить его на setTimeout и вызвать его рекурсивно.
Итак, у меня есть:
Переменная таймера
this.timeOut = false;
Эти две функции для включения или остановки карусели:
stopSlide() {
console.log('stop', this.timeOut);
if (this.timeOut) {
window.clearTimeout(this.timeOut);
this.timeOut = null;
delete this.timeOut;
}
}
startSlide() {
this.stopSlide();
const hasMoreThanOneSlide = this.ribbon.querySelectorAll('.pts-desktop-header-ribbon__item').length > 1;
this.timeOut = hasMoreThanOneSlide ? window.setTimeout(() => this.doPlay(this.play), this.time) : null;
console.log('start', this.timeOut);
}
И эта, которая ее воспроизводит(удаляя некоторые индексные переменные и прочее, чтобы вопрос не был слишком большим):
doPlay(element) {
const newScroll = element.classList.contains(BUTTON_LEFT_CLASS) ? 1 : -1;
const totalItems = this.el.querySelectorAll(`.${BASE_LIST_ITEM}`).length - 1;
/* Update current */
this.current++; // this wasn't like this cause actually i can turn +1 or -1 but I don't want to make this question longer
/* Update visible */
this.lists.forEach((list) => {
list.style.transform = `translate(${-this.current * 100}%)`;
});
/* Update visible class */
this.updateCurrentRibbonElement();
if (this.timeOut) {
this.stopSlide();
this.startSlide(); // Calls the setTimeout function again
} else {
this.stopSlide();
}
}
И вот как я его инициализирую:
events.delegate(this.el, `.${BUTTON_CLASS}`, 'click', (e) => {
this.stopSlide();
this.doPlay(e.elementTarget);
this.hideRibbon();
});
/* Start interval */
this.startSlide();
Полный класс (в синтаксисе Webpack) можетможно найти здесь: https://jsfiddle.net/toz4xafu/
Так что проблема в том, что Иногда , при использовании стрелок очень быстро (подчеркивая приложение) кажется, что не очищает this.timeOut
var, и этовыполнено несколько раз (вместо 7 секунд это 2-4 секунды)
Вопрос в том, как я могу сделатьВы уверены, что у меня не будет больше одного таймаута?
Кстати, есть ли способ отладить, сколько тиммеров выполняется?