refactor: ♻️ clean up gallery code

- cast images collection to array for clarity in galleryObserver
- shorten debounce function
- do not destructure track object for isAtEnd (no space savings or readability improvements)
- remove unused argument in updateActiveStates
- call functions directly during page initialization
This commit is contained in:
Sebin Nyshkim 2025-06-10 17:14:54 +02:00
parent 778e206f9a
commit c40d7d1ec8

View file

@ -1,7 +1,7 @@
<script> <script>
const gallery = document.querySelector('.gallery'); const gallery = document.querySelector('.gallery');
const track = gallery.querySelector('.track'); const track = gallery.querySelector('.track');
const images = gallery.querySelectorAll('.track > *'); const images = Array.from(gallery.querySelectorAll('.track > *'));
const nav = gallery.querySelector('.gallery-nav'); const nav = gallery.querySelector('.gallery-nav');
const prevButton = gallery.querySelector('button.prev'); const prevButton = gallery.querySelector('button.prev');
const nextButton = gallery.querySelector('button.next'); const nextButton = gallery.querySelector('button.next');
@ -9,24 +9,16 @@
const TOLERANCE = 2; const TOLERANCE = 2;
const debounce = (fn, delay = 300) => { const debounce = (fn, delay = 300) => {
let timer = 0; let timer;
const debounced = (...args) => { return function (...args) {
if (!args) args = [];
clearTimeout(timer); clearTimeout(timer);
timer = setTimeout(() => fn.apply(fn, args), delay);
timer = setTimeout(() => {
fn.apply(fn, args);
}, delay);
}; };
return debounced;
}; };
const isAtStart = () => Math.floor(track.scrollLeft) <= TOLERANCE; const isAtStart = () => Math.floor(track.scrollLeft) <= TOLERANCE;
const isAtEnd = () => { const isAtEnd = () =>
const { scrollLeft, offsetWidth, scrollWidth } = track; Math.abs(track.scrollLeft + track.offsetWidth - track.scrollWidth) <= TOLERANCE;
return Math.abs(scrollLeft + offsetWidth - scrollWidth) <= TOLERANCE;
};
const updateAriaCurrent = (element, index) => { const updateAriaCurrent = (element, index) => {
currentIndex === index currentIndex === index
@ -34,7 +26,7 @@
: element.removeAttribute('aria-current'); : element.removeAttribute('aria-current');
}; };
const updateActiveStates = (index) => { const updateActiveStates = () => {
images.forEach(updateAriaCurrent); images.forEach(updateAriaCurrent);
nav.querySelectorAll('.indicator-btn').forEach(updateAriaCurrent); nav.querySelectorAll('.indicator-btn').forEach(updateAriaCurrent);
prevButton.disabled = isAtStart(); prevButton.disabled = isAtStart();
@ -49,7 +41,7 @@
currentIndex = index; currentIndex = index;
images[index].scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' }); images[index].scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' });
updateActiveStates(index); updateActiveStates();
}; };
const prev = () => scrollToIndex(currentIndex - 1); const prev = () => scrollToIndex(currentIndex - 1);
@ -62,10 +54,10 @@
(entries) => { (entries) => {
entries.forEach((entry) => { entries.forEach((entry) => {
if (entry.isIntersecting && entry.intersectionRatio >= 0.75) { if (entry.isIntersecting && entry.intersectionRatio >= 0.75) {
const index = [...images].indexOf(entry.target); const index = images.indexOf(entry.target);
if (index !== -1) { if (index !== -1) {
currentIndex = index; currentIndex = index;
updateActiveStates(currentIndex); updateActiveStates();
} }
} }
}); });
@ -92,14 +84,14 @@
nav.appendChild(btn); nav.appendChild(btn);
}); });
updateActiveStates(0); updateActiveStates();
}; };
images.forEach((el) => galleryObserver.observe(el)); images.forEach((el) => galleryObserver.observe(el));
prevButton.addEventListener('click', prev); prevButton.addEventListener('click', prev);
nextButton.addEventListener('click', next); nextButton.addEventListener('click', next);
track.addEventListener('scroll', () => debounce(updateActiveStates(currentIndex))); track.addEventListener('scroll', debounce(updateActiveStates, 100));
document.addEventListener('DOMContentLoaded', () => initializeGallery()); document.addEventListener('DOMContentLoaded', initializeGallery);
</script> </script>
<section aria-label="Image gallery" webc:root="override"> <section aria-label="Image gallery" webc:root="override">