5.1 Modern JavaScript Patterns
We use ES6 classes, arrow functions, destructuring, and template literals where they improve code readability and maintainability. However, we don’t use new features just for the sake of using them: each language feature should serve a purpose in making our code clearer or more efficient.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// Component-based JavaScript for both WordPress and Laravel
class ImageGallery {
constructor(element, options = {}) {
this.element = element;
this.options = {
autoplay: false,
showThumbnails: true,
...options
};
this.currentIndex = 0;
this.images = this.element.querySelectorAll('.gallery-image');
this.init();
}
init() {
this.bindEvents();
if (this.options.autoplay) {
this.startAutoplay();
}
}
bindEvents() {
const nextBtn = this.element.querySelector('.gallery-next');
const prevBtn = this.element.querySelector('.gallery-prev');
nextBtn?.addEventListener('click', () => this.next());
prevBtn?.addEventListener('click', () => this.previous());
// Keyboard accessibility
this.element.addEventListener('keydown', (e) => {
if (e.key === 'ArrowRight') this.next();
if (e.key === 'ArrowLeft') this.previous();
});
}
next() {
this.currentIndex = (this.currentIndex + 1) % this.images.length;
this.updateDisplay();
}
previous() {
this.currentIndex = this.currentIndex === 0
? this.images.length - 1
: this.currentIndex - 1;
this.updateDisplay();
}
updateDisplay() {
this.images.forEach((img, index) => {
img.classList.toggle('active', index === this.currentIndex);
});
}
}
// Initialize galleries
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('.image-gallery').forEach(gallery => {
new ImageGallery(gallery);
});
});