Skip to content

Carousel - second refactor

Unsere EventListener sehen jetzt so aus:

nextButton.addEventListener('click', e => {
const currentSlide = contents.querySelector('.is-selected')
const currentDot = dotsContainer.querySelector('.is-selected')
const nextSlide = currentSlide.nextElementSibling
const nextSlideIndex = slides.findIndex(slide => slide === nextSlide)
const nextDot = currentDot.nextElementSibling
switchSlides(currentSlide, nextSlide)
highlightDot(currentDot, nextDot)
showHideArrowButtons(nextSlideIndex)
})
previousButton.addEventListener('click', e => {
const currentSlide = contents.querySelector('.is-selected')
const currentDot = dotsContainer.querySelector('.is-selected')
const previousSlide = currentSlide.previousElementSibling
const previousSlideIndex = slides.findIndex(slide => slide === previousSlide)
const previousDot = currentDot.previousElementSibling
switchSlides(currentSlide, previousSlide)
highlightDot(currentDot, previousDot)
showHideArrowButtons(previousSlideIndex)
})
dotsContainer.addEventListener('click', e => {
const dot = e.target.closest('button')
if (!dot) return
const currentSlide = contents.querySelector('.is-selected')
const currentDot = dotsContainer.querySelector('.is-selected')
const targetSlideIndex = dots.findIndex(d => d === dot)
const slideToShow = slides[targetSlideIndex]
switchSlides(currentSlide, slideToShow)
highlightDot(currentDot, dot)
showHideArrowButtons(targetSlideIndex)
})

Das sieht ja schon ziemlich gut aus! Wir können allerdings noch eine Sache verbessern. Wenn wir uns den nextButton EventListener anschauen, sehen wir, dass drei Arten von Werten verwendet werden:

  • slides
  • dots
  • indexes Wir könnten in allen Funktionen Indexwerte verwenden, da wir sowohl die Slides als auch die Dots vom Index ableiten können.

In switchSlides würden wir zwei verschiedene Indexwerte erwarten:

  • den Index des aktuellen Slides
  • den Index des neuen Slides

Wir müssen currentSlide und targetSlide aus currendSlideIndex bzw. targetSlideIndex ableiten.

function switchSlide(currentSlideIndex, targetSlideIndex) {
const currentSlide = slides[currentSlideIndex]
const targetSlide = slides[targetSlideIndex]
const destination = getComputedStyle(targetSlide).left
contents.style.transform = `translateX(-${destination})`
currentSlide.classList.remove('is-selected')
targetSlide.classList.add('is-selected')
}

Verwendung der neuen switchSlide Funktion:
Wir brauchen nicht mehr nach nextSlide zu suchen. Wir können den Index von currentSlide mit findIndex feststellen. nextSlide ist dann einfach currentSlideIndex + 1.

nextButton.addEventListener('click', e => {
const currentSlide = contents.querySelector('.is-selected')
const currentSlideIndex = slides.findIndex(slide => slide === currentSlide)
const nextSlideIndex = currentSlideIndex + 1
const currentDot = dotsContainer.querySelector('.is-selected')
const nextDot = currentDot.nextElementSibling
switchSlide(currentSlideIndex, nextSlideIndex)
highlightDot(currentDot, dot)
showHideArrowButtons(nextSlideIndex)
})
previousButton.addEventListener('click', e => {
const currentSlide = contents.querySelector('.is-selected')
const currentSlideIndex = slides.findIndex(slide => slide === currentSlide)
const previousSlideIndex = currentSlideIndex - 1
const currentDot = dotsContainer.querySelector('.is-selected')
const previousDot = currentDot.previousElementSibling
switchSlide(currentSlideIndex, prevSlideIndex)
highlightDot(currentDot, dot)
showHideArrowButtons(previousSlideIndex)
})
dotsContainer.addEventListener('click', e => {
const dot = e.target.closest('button')
if (!dot) return
const currentSlide = contents.querySelector('.is-selected')
const currentSlideIndex = slides.findIndex(slide => slide === currentSlide)
const currentDot = dotsContainer.querySelector('.is-selected')
const targetSlideIndex = dots.findIndex(d => d === dot)
switchSlide(currentSlideIndex, targetSlideIndex)
highlightDot(currentDot, dot)
showHideArrowButtons(targetSlideIndex)
})
function highlightDot(currentDot, targetDot) {
currentDot.classList.remove('is-selected')
targetDot.classList.add('is-selected')
}

Wir wissen, dass der Indexwert für currentDot gleich ist wie currentSlideIndex, gleiches gilt für targetDot und targetSlideIndex. Das gilt wieder für alle drei EventListener.

Wir können also currentDot und highlightDot ersetzen, wenn wir die Dots über den Index finden.

function highlightDot(currentDotIndex, targetSlideIndex) {
const currentDot = dots[currentSlideIndex]
const targetDot = dots[targetSlideIndex]
currentDot.classList.remove('is-selected')
targetDot.classList.add('is-selected')
}

Verwendung der neuen highlightDot Funktion:
const currentDot = ... und const nextDot = ... werden nicht mehr benötigt und können gelöscht werden!

nextButton.addEventListener('click', e => {
const currentSlide = contents.querySelector('.is-selected')
const currentSlideIndex = slides.findIndex(slide => slide === currentSlide)
const nextSlideIndex = currentSlideIndex + 1
switchSlide(currentSlideIndex, nextSlideIndex)
highlightDot(currentSlideIndex, nextSlideIndex)
showHideArrowButtons(nextSlideIndex)
})
previousButton.addEventListener('click', e => {
const currentSlide = contents.querySelector('.is-selected')
const currentSlideIndex = slides.findIndex(slide => slide === currentSlide)
const previousSlideIndex = currentSlideIndex - 1
switchSlide(currentSlideIndex, previousSlideIndex)
highlightDot(currentSlideIndex, previousSlideIndex)
showHideArrowButtons(previousSlideIndex)
})
dotsContainer.addEventListener('click', e => {
const dot = e.target.closest('button')
if (!dot) return
const currentSlide = contents.querySelector('.is-selected')
const currentSlideIndex = slides.findIndex(slide => slide === currentSlide)
const targetSlideIndex = dots.findIndex(d => d === dot)
switchSlide(currentSlideIndex, targetSlideIndex)
highlightDot(currentSlideIndex, targetSlideIndex)
showHideArrowButtons(targetSlideIndex)
})

Jetzt können wir auch erkennen, warum wir das gemacht haben: alle drei EventListener verwenden diesen Code, um den currentSlideIndex zu bekommen:

const currentSlide = contents.querySelector('.is-selected')
const currentSlideIndex = slides.findIndex(slide => slide === currentSlide)

Daraus lässt sich wieder eine Funktion basteln:

function getCurrentSlideIndex() {
const currentSlide = contents.querySelector('.is-selected')
const currentSlideIndex = slides.findIndex(slide => slide === currentSlide)
return currentSlideIndex
}
// shorter version
function getCurrentSlideIndex() {
const currentSlide = contents.querySelector('.is-selected')
return slides.findIndex(slide => slide === currentSlide)
}

Verwendung:

nextButton.addEventListener('click', e => {
const currentSlideIndex = getCurrentSlideIndex()
const nextSlideIndex = currentSlideIndex + 1
// ...
})
previousButton.addEventListener('click', e => {
const currentSlideIndex = getCurrentSlideIndex()
const previousSlideIndex = currentSlideIndex + 1
// ...
})
dotsContainer.addEventListener('click', e => {
// ...
const currentSlideIndex = getCurrentSlideIndex()
const targetSlideIndex = dots.findIndex(d => d === dot)
// ...
})