class SliderComponentSlideShow extends HTMLElement { constructor() { super(); this.slider = this.querySelector('[id^="Slider-"]'); this.sliderItems = this.querySelectorAll('[id^="Slide-"]'); this.enableSliderLooping = false; this.currentPageElement = this.querySelector('.slider-counter--current'); this.pageTotalElement = this.querySelector('.slider-counter--total'); this.prevButton = this.querySelector('button[name="previous"]'); this.nextButton = this.querySelector('button[name="next"]'); if (!this.slider || !this.nextButton) return; this.initPages(); const resizeObserver = new ResizeObserver(entries => this.initPages()); resizeObserver.observe(this.slider); this.slider.addEventListener('scroll', this.update.bind(this)); this.prevButton.addEventListener('click', this.onButtonClick.bind(this)); this.nextButton.addEventListener('click', this.onButtonClick.bind(this)); } initPages() { this.sliderItemsToShow = Array.from(this.sliderItems).filter(element => element.clientWidth > 0); this.sliderLastItem = this.sliderItemsToShow[this.sliderItemsToShow.length - 1]; if (this.sliderItemsToShow.length === 0) return; this.slidesPerPage = Math.floor(this.slider.clientWidth / this.sliderItemsToShow[0].clientWidth); this.totalPages = this.sliderItemsToShow.length - this.slidesPerPage + 1; this.update(); } resetPages() { this.sliderItems = this.querySelectorAll('[id^="Slide-"]'); this.initPages(); } update() { const previousPage = this.currentPage; this.currentPage = Math.round(this.slider.scrollLeft / this.sliderLastItem.clientWidth) + 1; if (this.currentPageElement && this.pageTotalElement) { this.currentPageElement.textContent = this.currentPage; this.pageTotalElement.textContent = this.totalPages; } if (this.currentPage != previousPage) { this.dispatchEvent(new CustomEvent('slideChanged', { detail: { currentPage: this.currentPage, currentElement: this.sliderItemsToShow[this.currentPage - 1] } })); } if (this.enableSliderLooping) return; if (this.isSlideVisible(this.sliderItemsToShow[0])) { this.prevButton.setAttribute('disabled', 'disabled'); } else { this.prevButton.removeAttribute('disabled'); } if (this.isSlideVisible(this.sliderLastItem)) { this.nextButton.setAttribute('disabled', 'disabled'); } else { this.nextButton.removeAttribute('disabled'); } } isSlideVisible(element, offset = 0) { const lastVisibleSlide = this.slider.clientWidth + this.slider.scrollLeft - offset; return (element.offsetLeft + element.clientWidth) <= lastVisibleSlide && element.offsetLeft >= this.slider.scrollLeft; } onButtonClick(event) { event.preventDefault(); const step = event.currentTarget.dataset.step || 1; this.slideScrollPosition = event.currentTarget.name === 'next' ? this.slider.scrollLeft + (step * this.sliderLastItem.clientWidth) : this.slider.scrollLeft - (step * this.sliderLastItem.clientWidth); this.slider.scrollTo({ left: this.slideScrollPosition }); } } customElements.define('slider-component-slideshow', SliderComponentSlideShow); class SlideshowComponent extends SliderComponentSlideShow { constructor() { super(); this.sliderControlWrapper = this.querySelector('.slider-buttons'); this.enableSliderLooping = true; if (!this.sliderControlWrapper) return; this.sliderFirstItemNode = this.slider.querySelector('.slideshow__slide'); if (this.sliderItemsToShow.length > 0) this.currentPage = 1; this.sliderControlLinksArray = Array.from(this.sliderControlWrapper.querySelectorAll('.slider-counter__link')); this.sliderControlLinksArray.forEach(link => link.addEventListener('click', this.linkToSlide.bind(this))); this.slider.addEventListener('scroll', this.setSlideVisibility.bind(this)); this.setSlideVisibility(); if (this.slider.getAttribute('data-autoplay') === 'true') this.setAutoPlay(); } setAutoPlay() { this.sliderAutoplayButton = this.querySelector('.slideshow__autoplay'); this.autoplaySpeed = this.slider.dataset.speed * 1000; this.sliderAutoplayButton.addEventListener('click', this.autoPlayToggle.bind(this)); this.addEventListener('mouseover', this.focusInHandling.bind(this)); this.addEventListener('mouseleave', this.focusOutHandling.bind(this)); this.addEventListener('focusin', this.focusInHandling.bind(this)); this.addEventListener('focusout', this.focusOutHandling.bind(this)); this.play(); this.autoplayButtonIsSetToPlay = true; } onButtonClick(event) { super.onButtonClick(event); const isFirstSlide = this.currentPage === 1; const isLastSlide = this.currentPage === this.sliderItemsToShow.length; if (!isFirstSlide && !isLastSlide) return; if (isFirstSlide && event.currentTarget.name === 'previous') { this.slideScrollPosition = this.slider.scrollLeft + this.sliderFirstItemNode.clientWidth * this.sliderItemsToShow.length; } else if (isLastSlide && event.currentTarget.name === 'next') { this.slideScrollPosition = 0; } this.slider.scrollTo({ left: this.slideScrollPosition }); } update() { super.update(); this.sliderControlButtons = this.querySelectorAll('.slider-counter__link'); this.prevButton.removeAttribute('disabled'); if (!this.sliderControlButtons.length) return; this.sliderControlButtons.forEach(link => { link.classList.remove('slider-counter__link--active'); link.removeAttribute('aria-current'); }); this.sliderControlButtons[this.currentPage - 1].classList.add('slider-counter__link--active'); this.sliderControlButtons[this.currentPage - 1].setAttribute('aria-current', true); } autoPlayToggle() { this.togglePlayButtonState(this.autoplayButtonIsSetToPlay); this.autoplayButtonIsSetToPlay ? this.pause() : this.play(); this.autoplayButtonIsSetToPlay = !this.autoplayButtonIsSetToPlay; } focusOutHandling(event) { const focusedOnAutoplayButton = event.target === this.sliderAutoplayButton || this.sliderAutoplayButton.contains(event.target); if (!this.autoplayButtonIsSetToPlay || focusedOnAutoplayButton) return; this.play(); } focusInHandling(event) { const focusedOnAutoplayButton = event.target === this.sliderAutoplayButton || this.sliderAutoplayButton.contains(event.target); if (focusedOnAutoplayButton && this.autoplayButtonIsSetToPlay) { this.play(); } else if (this.autoplayButtonIsSetToPlay) { this.pause(); } } play() { this.slider.setAttribute('aria-live', 'off'); clearInterval(this.autoplay); this.autoplay = setInterval(this.autoRotateSlides.bind(this), this.autoplaySpeed); } pause() { this.slider.setAttribute('aria-live', 'polite'); clearInterval(this.autoplay); } togglePlayButtonState(pauseAutoplay) { if (pauseAutoplay) { this.sliderAutoplayButton.classList.add('slideshow__autoplay--paused'); this.sliderAutoplayButton.setAttribute('aria-label', window.accessibilityStrings.playSlideshow); } else { this.sliderAutoplayButton.classList.remove('slideshow__autoplay--paused'); this.sliderAutoplayButton.setAttribute('aria-label', window.accessibilityStrings.pauseSlideshow); } } autoRotateSlides() { const slideScrollPosition = this.currentPage === this.sliderItems.length ? 0 : this.slider.scrollLeft + this.slider.querySelector('.slideshow__slide').clientWidth; this.slider.scrollTo({ left: slideScrollPosition }); } setSlideVisibility() { this.sliderItemsToShow.forEach((item, index) => { const button = item.querySelector('a'); if (index === this.currentPage - 1) { if (button) button.removeAttribute('tabindex'); item.setAttribute('aria-hidden', 'false'); item.removeAttribute('tabindex'); } else { if (button) button.setAttribute('tabindex', '-1'); item.setAttribute('aria-hidden', 'true'); item.setAttribute('tabindex', '-1'); } }); } linkToSlide(event) { event.preventDefault(); const slideScrollPosition = this.slider.scrollLeft + this.sliderFirstItemNode.clientWidth * (this.sliderControlLinksArray.indexOf(event.currentTarget) + 1 - this.currentPage); this.slider.scrollTo({ left: slideScrollPosition }); } } customElements.define('slideshow-component', SlideshowComponent);