Refactoring the dots part
Zur Wiederholung, das ist der Code für die Dots:
dotsContainer.addEventListener('click', e => { const dot = e.target.closest('button') if (!dot) return
const clickedDotIndex = dots.findIndex(d => d === dot)
const slideToShow = slides[clickedDotIndex] const destination = getComputedStyle(slideToShow).left contents.style.transform = `translateX(-${destination})`
// add/remove is-selected to the slides slides.forEach(slide => { slide.classList.remove('is-selected') }) slideToShow.classList.add('is-selected')
// update the dot state dots.forEach(d => { d.classList.remove('is-selected') }) dot.classList.add('is-selected')
// show/hide the buttons if (clickedDotIndex === 0) { previousButton.setAttribute('hidden', true) nextButton.removeAttribute('hidden') } else if (clickedDotIndex === dots.length - 1) { previousButton.removeAttribute('hidden') nextButton.setAttribute('hidden', true) } else { previousButton.removeAttribute('hidden') nextButton.removeAttribute('hidden') }})Wir gehen das nochmal Schritt für Schritt durch:
Deciding whether to act on the dots
Section titled “Deciding whether to act on the dots”dotsContainer.addEventListener('click', e => { const dot = e.target.closest('button') if (!dot) return // ...})Wir packen den angeklickten Dot in eine Variable dot und benutzen dafür das Event Delegation pattern. Wir wollen nicht über die einzelnen Dots iterieren, sondern nur auf einen Klick auf den DotContainer lauschen. Dabei sollen alle Klicks, die zwischen den Buttons landen, herausgefiltert werden. Wenn das Klickziel also kein Dot ist, verlassen wir den EventListener. Diese beiden Zeilen müssen im EventListener bleiben.
Getting the variables
Section titled “Getting the variables”dotsContainer.addEventListener('click', e => { // ... const clickedDotIndex = dots.findIndex(d => d === dot) const slideToShow = slides[clickedDotIndex]})Die nächsten beiden Variablen beinhalten Ziel-Dot und Ziel-Slide. Beide sind essentiell für den EventListener und bleiben auch, wo sie sind.
Showing the slides
Section titled “Showing the slides”Die nächsten vier Zeilen wechseln die Slides. Sie sind dem Code der Funktion switchSlides sehr ähnlich.
dotsContainer.addEventListener('click', e => { // ... const destination = getComputedStyle(slideToShow).left contents.style.transform = `translateX(-${destination})` slides.forEach(slide => { slide.classList.remove('is-selected') }) slide.classList.add('is-selected')})function switchSlides(currentSlide, targetSlide) { const destination = getComputedStyle(targetSlide).left
contents.style.transform = `translateX(-${destination})` currentSlide.classList.remove('is-selected') targetSlide.classList.add('is-selected')}Der Hauptunterschied besteht darin, dass wir bei den Dots über die Slides iterieren um die Klasse is-selected zu entfernen, in der Funktion die Klasse aber direkt von currentSlide entfernen und dem next/previousSlide hinzufügen. Das können wir vereinheitlichen und somit die Funktion auch im Dot EventListener verwenden.
Wir müssen also currentSlide im DotEventListener finden, das geht mit querySelector. Dann ersetzen wir die Schleife durch die nicht-iterative Version:
dotsContainer.addEventListener('click', e => { // ... const currentSlide = contents.querySelector('.is-selected') const clickedDotIndex = dots.findIndex(d => d === dot) const slideToShow = slides[clickedDotIndex]
currentSlide.classList.remove('is-selected') slideToShow.classList.add('is-selected')})Und nun können wir die Funktion switchSlides im DotEventListener verwenden:
dotsContainer.addEventListener('click', e => { // ... const currentSlide = contents.querySelector('.is-selected') const clickedDotIndex = dots.findIndex(d => d === dot) const slideToShow = slides[clickedDotIndex]
switchSlides(currentSlide, slideToShow)})Highlighting dots
Section titled “Highlighting dots”Analog können wir bei den hervorgehobenen Dots vorgehen: Der Code ist jeweils ähnlich, im Dot EventListener und in der Funktion highlightDot.
dotsContainer.addEventListener('click', e => { // ... // highligt dot dots.forEach(d => { d.classList.remove('is-selected') }) dot.classList.add('is-selected')})function highlightDot(currentDot, targetDot) { currentDot.classList.remove('is-selected') targetDot.classList.add('is-selected')}Um konsistent zu bleiben, werden wir im Dot EventListener auch die nicht-iterative Form verwenden. Dazu müssen wir den currentDot mit querySelector suchen:
dotsContainer.addEventListener('click', e => { // ... // highlight dot const currentDot = dotsContainer.querySelector('.is-selected') currentDot.classList.remove('is-selected') dot.classList.add('is-selected')})Verwendung der Funktion hightlightDot im Dots EventListener:
dotsContainer.addEventListener('click', e => { // ... // highlight dot const currentDot = dotsContainer.querySelector('.is-selected') highlightDot(currentDot, dot)})Showing/hiding prev and next buttons
Section titled “Showing/hiding prev and next buttons”Zur Erinnerung: wir haben diesen (imperativen) Code zur Anzeige bzw. zum Verstecken der prev/next Buttons verwendet:
dotsContainer.addEventListener('click', e => { // ... // show/hide the buttons if (clickedDotIndex === 0) { previousButton.setAttribute('hidden', true) nextButton.removeAttribute('hidden') } else if (clickedDotIndex === dots.length - 1) { previousButton.removeAttribute('hidden') nextButton.setAttribute('hidden', true) } else { previousButton.removeAttribute('hidden') nextButton.removeAttribute('hidden') }})Als erstes packen wir den gesamten Code in eine Funktion showHideArrowButtons:
function showHideArrowButtons() { if (clickedDotIndex === 0) { previousButton.setAttribute('hidden', true) nextButton.removeAttribute('hidden') } else if (clickedDotIndex === dots.length - 1) { previousButton.removeAttribute('hidden') nextButton.setAttribute('hidden', true) } else { previousButton.removeAttribute('hidden') nextButton.removeAttribute('hidden') }}Nun sehen wir, dass wir dafür vier Variablen brauchen:
clickedDotIndexdotspreviousButtonnextButton
Drei davon, dots, previousButton und nextButton bekommen wir aus dem global scope. Dann müssen wir der Funktion nur mehr ein Argument, nämlich clickedDotIndex übergeben:
function showHideArrowButtons(clickedDotIndex) { // ...}dotsContainer.addEventListener('click', e => { // ... showHideArrowButtons(clickedDotIndex)})