wcia-photo-carousel is a custom HTML element for displaying an album title, author, photo list, current image, and back/forward controls. section 2.6
Configure the element through attributes and implement it with a small HTMLElement subclass:
- Pass title, author, and comma-separated photo URLs as HTML attributes. section 2.6
- Register the tag with customElements.define and initialize it in connectedCallback. section 2.6
- Render the heading, image container, and navigation buttons with innerHTML. section 2.6
- Track the current photo index, display its URL, and wrap navigation at both ends. section 2.6
Using the carousel
<wcia-photo-carousel title="Future Vacation Photos" author="Ben Farrell" photos="images/fBmIASF.jpg,images/3zxD6rz.jpg,images/nKBgeLOr.jpg,images/yVjJZ1Yr.jpg"></wcia-photo-carousel> section 2.6
Listing 2.15. Demo code recap
<html>
<head>
<title>Photo Carousel</title>
<script>
class PhotoCarousel extends HTMLElement { #1
connectedCallback() {
this._photoIndex = 0;
this._photos = this.getAttribute('photos').split(',');
this.innerHTML = '<h2>'+ this.getAttribute('title') + '</h2>' +
'<h4>by '+ this.getAttribute('author') + '</h4>' +
'<div class="image-container"></div>' +
'<button class="back"><</button>' +
'<button class="forward"> #2
>
</button>';
this.showPhoto();
this.querySelector('button.back').addEventListener('click',#3
event => this.onBackButtonClick(event));
this.querySelector('button.forward').addEventListener('click',
event =>
this.onForwardButtonClick(event));
}
/**
* handler for when user clicks the back button
* @param event
*/
onBackButtonClick(event) { #4
this._photoIndex --;
if (this._photoIndex < 0) {
this._photoIndex = this._photos.length-1;
}
this.showPhoto();
}
/**
* handler for when user clicks the forward button
* @param event
*/
onForwardButtonClick(event) { #5
this._photoIndex ++;
if (this._photoIndex >= this._photos.length) {
this._photoIndex = 0;
}
this.showPhoto();
}
showPhoto() { #6
this.querySelector('.image-container').style.backgroundImage
= 'url(' + this._photos[this._photoIndex] + ')';
}
}
if (!customElements.get( #7
'wcia-photo-carousel')) {
customElements.define('wcia-photo-carousel', PhotoCarousel);
}
</script>
<style> #8
wcia-photo-carousel {
position: relative;
width: 500px;
height: 300px;
display: flex;
padding-top: 10px;
flex-direction: column;
border-color: black;
border-width: 1px;
border-style: solid;
}
wcia-photo-carousel h2, h4 {
margin-bottom: 0;
margin-top: 0;
margin-left: 10px;
}
wcia-photo-carousel .image-container {
margin-top: 15px;
flex: 1;
background-color: black;
background-size: contain;
background-repeat: no-repeat;
background-position: 50%;
}
wcia-photo-carousel button {
cursor: pointer;
background: transparent;
border: none;
font-size: 48px;
color: white;
position: absolute;
top: 50%;
}
wcia-photo-carousel button.back {
left: 10px;
}
wcia-photo-carousel button.forward {
right: 10px;
}
</style>
</head>
<body>
<wcia-photo-carousel #9
title="Future Vacation Photos"
author="Ben Farrell"
photos="images/fBmIASF.jpg,images/3zxD6rz.jpg,images/
nKBgeLOr.jpg,images/yVjJZ1Yr.jpg">
</wcia-photo-carousel>
</body>
</html>
Browse the complete demo recap, including registration, rendering, image display, and button listeners. section 2.6
