Skip to content

Instantly share code, notes, and snippets.

@macdonst
Created Jan 19, 2023
Embed
What would you like to do?
Slide show using attribute as source of truth for location in slideshow
class SlideShow extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({mode:'open'});
if(!this.hasAttribute('images')) {
console.warn('slide-show called with no images');
return;
}
/*
Convert attribute into an array and do some trimming so that the end user can have some spacing
*/
this.images = this.getAttribute('images').split(',').map(i => i.trim());
this.totalImages = this.images.length;
// marker for what image to show, can be passed as an attribute, 1 based
if(this.hasAttribute('current')) {
this.current = parseInt(this.getAttribute('current'), 0);
console.log(this.current)
if(this.current > this.totalImages) this.current = 0;
} else this.current = 0;
const wrapper = document.createElement('div');
wrapper.innerHTML = `
<img id="currentImage" src="${this.images[this.current]}">
<p>
<button id="prevButton">Previous</button>
<button id="nextButton">Next</button>
</p>
`;
this.$nextButton = wrapper.querySelector('#nextButton');
this.$prevButton = wrapper.querySelector('#prevButton');
this.$image = wrapper.querySelector('#currentImage');
shadow.appendChild(wrapper);
}
static get observedAttributes() {
return ['current'];
}
attributeChangedCallback(name, oldValue, newValue) {
if (oldValue !== newValue) {
this.updateImage(newValue);
}
}
get current() {
// Attributes come back as strings so I have to coerce to a integer
return parseInt(this.getAttribute('current'), 10);
}
set current(value) {
this.setAttribute('current', value);
}
connectedCallback() {
console.log('connected');
this.$nextButton.addEventListener('click', this.nextImage.bind(this));
this.$prevButton.addEventListener('click', this.prevImage.bind(this));
}
nextImage() {
this.current+1 === this.totalImages ? this.current = 0 : this.current++;
}
prevImage() {
this.current === 0 ? this.current = this.totalImages - 1: this.current--;
}
updateImage(idx) {
this.$image.src = this.images[idx];
}
}
customElements.define('slide-show', SlideShow);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment