Last active
November 23, 2021 15:23
-
-
Save aaron-watts/af7018d4e3075238954a1ac5e8b6ca7b to your computer and use it in GitHub Desktop.
A JS Carousel Class to handle Carousels and Paginations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Carousel(query, options) | |
* query - top level element selector | |
* options - { | |
* indicators: true/'interactive', // interactive creates clickable indicators | |
* step: true, // next/previous buttons | |
* auto: true // timed next calls | |
* } | |
*/ | |
export class Carousel { | |
constructor(_query, _options = {}) { | |
this.query = _query; | |
this.carousel = document.querySelector(`${this.query}__slides`); | |
this.slides = document.querySelectorAll(`${this.query}__item`); | |
this.currentSlide = 0; | |
this.width = this.carousel.clientWidth; | |
if (_options.indicators) { | |
this.progress = document.querySelector(`${this.query}__progress`); | |
this.counters = this.progress.children; | |
} | |
if (_options.indicators === 'interactive') { | |
[...this.counters].forEach((counter, i, all) => { | |
counter.addEventListener('click', () => { | |
this.currentSlide = all.indexOf(counter); | |
this.carousel.scrollTo(this.currentSlide * this.width, 0); | |
Carousel.updateIndicator(this); | |
}); | |
}); | |
} | |
if (_options.step) { | |
this.steppers = document.querySelectorAll(`${this.query}__control`); | |
this.controls = { | |
previous: [...this.steppers].filter(i => i.classList.contains('previous'))[0], | |
next: [...this.steppers].filter(i => i.classList.contains('next'))[0] | |
}; | |
this.controls.previous.addEventListener('click', () => { | |
clearInterval(this.interval); | |
this.previous(); | |
if (_options.auto) this.interval = this.scrollInterval(); | |
}); | |
this.controls.next.addEventListener('click', () => { | |
clearInterval(this.interval); | |
this.next(); | |
if (_options.auto) this.interval = this.scrollInterval(); | |
}); | |
} | |
if (_options.auto) { | |
this.interval = this.scrollInterval(); | |
} | |
}; | |
get lastSlide() { | |
return this.slides.length - 1; | |
} | |
static updateIndicator(carousel) { | |
[...carousel.counters].forEach(i => i.classList.remove('active')); | |
carousel.counters[carousel.currentSlide].classList.add('active'); | |
} | |
scrollInterval() { | |
return setInterval(() => this.next(), 5000); | |
}; | |
next() { | |
if (this.currentSlide < this.lastSlide) { | |
this.carousel.scrollBy({ left: this.width }); | |
this.currentSlide++; | |
} else { | |
this.carousel.scrollTo(0, 0); | |
this.currentSlide = 0; | |
} | |
if (this.progress) { | |
Carousel.updateIndicator(this); | |
} | |
}; | |
previous() { | |
if (this.currentSlide > 0) { | |
this.carousel.scrollBy({ left: -this.width }); | |
this.currentSlide--; | |
} else { | |
this.carousel.scrollTo({ left: this.lastSlide * this.width }); | |
this.currentSlide = this.lastSlide; | |
} | |
if (this.progress) { | |
Carousel.updateIndicator(this); | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment