From: Andrew Lorimer Date: Thu, 23 Jun 2022 10:25:33 +0000 (+1000) Subject: initialise listeners in JS, set heights at runtime, add readme X-Git-Url: https://git.lorimer.id.au/simple-slideshow.git/diff_plain/a0b380c3049345ba70e7ae31917a210783ae814f?ds=inline initialise listeners in JS, set heights at runtime, add readme --- diff --git a/README.md b/README.md new file mode 100644 index 0000000..383134a --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# Simple JavaScript Slideshow + +This is a very basic slideshow made in JavaScript - no jQuery or other libraries. + +See slideshow.html for an example. To use, insert the HTML structure and link slideshow.css and slideshow.js. + +## Features + +- Auto advance (default 3 seconds, but you can change `INTERVAL` in slideshow.js or in the HTML) +- Pause on hover and manual pause +- Scroll through slides with buttons or dot indicator at bottom +- Captions +- Semantic HTML (each slide is a `
` consisting of an `` and `
`) +- Sensible behaviour when JS is disabled (static first slide) +- Works with different sizes/aspect ratios and different length captions (set width or max-width of outer div, then slide heights are driven by the the height of the first slide at full width) +- Works well at all screen sizes and can be styled with basic CSS + +## Todo + +- Initialise slideshows with JS object +- Support for multiple slideshows per page diff --git a/slideshow.css b/slideshow.css index 552d5fb..3cd4ce0 100644 --- a/slideshow.css +++ b/slideshow.css @@ -23,9 +23,11 @@ figure.slide:first-child { figure.slide { /* Position slides absolutely to allow overlapping */ + text-align: center; position: absolute; top: 0; left: 0; + width: 100%; margin: 0; /* Slides start at 0 opacity */ opacity: 0; @@ -46,14 +48,8 @@ figure.slide.active { -moz-transition: opacity 1s ease; } -figure.slide *, -div.slideshow div#controls { - width: 100%; -} - -figure.slide figcaption { - height: var(--sl-cap); - text-align: center; +figure.slide img { + max-width: 100%; } @@ -76,7 +72,6 @@ figure.slide figcaption { top: calc(50% - calc(var(--sl-cap) + var(--sl-dots) + 50px) / 2); width: auto; padding: 16px; - border-radius: 0 3px 3px 0; } #state { @@ -90,6 +85,11 @@ figure.slide figcaption { border-radius: 3px; } +#prev { + left: 0; + border-radius: 0 3px 3px 0; +} + #next { /* Position next button on right */ right: 0; @@ -116,6 +116,7 @@ div.slideshow:hover #state { div.slideshow div#controls { text-align: center; + width: 100%; } div.slideshow div#controls span { diff --git a/slideshow.html b/slideshow.html index a581b1f..8896456 100644 --- a/slideshow.html +++ b/slideshow.html @@ -6,31 +6,34 @@ -
+
+
-
- -
This is a long caption yeah yeah yeah
-
+
+ +
This is a caption
+
-
- -
Shorter caption
-
+
+ +
This is a long caption which will probably span over multiple lines (depending on the width of the slideshow). You will see that that the height of the image adjusts to accommodate the taller caption.
+
-
- -
Caption 3
-
+
+ +
Caption 3
+
- - - ⏸︎ +
+ + + + ⏸︎
- - - + + +
diff --git a/slideshow.js b/slideshow.js index f73a888..80614c9 100644 --- a/slideshow.js +++ b/slideshow.js @@ -7,6 +7,9 @@ const STATE_PLAY = "⏵︎"; let currentSlide = -1; // Elements + +let slideshow = document.getElementsByClassName("slideshow")[0]; +let container = document.getElementsByClassName("slides")[0]; let slides = document.getElementsByClassName("slide"); let dots = document.getElementsByClassName("dot"); let stateBtn = document.getElementById("state"); @@ -16,21 +19,37 @@ let maxIndex = slides.length - 1; var timeout; var paused = false; +// Set up event listeners +window.addEventListener("resize", setHeights, true); +slideshow.addEventListener("mouseenter", mouseEnter, true); +slideshow.addEventListener("mouseleave", mouseLeave, true); +document.getElementById("prev").addEventListener("click", prevSlide); +document.getElementById("next").addEventListener("click", nextSlide); +document.getElementById("state").addEventListener("click", changeState); +if (dots.length - 1 != maxIndex) { + console.log("Number of control dots does not match number of slides"); +} +for (i = 0; i <= dots.length - 1; i++) { + dots[i].addEventListener("click", goToSlide); + dots[i].slide = i; +} + + // Start the slideshow playSlideshow(); // Recursive function that advances the slide and then calls itself with a // delay function playSlideshow() { + setHeights(); nextSlide(); timeout = setTimeout(playSlideshow, INTERVAL); } // Change the slide to a given index function setSlide(slide) { - if (slide < 0 || slide > maxIndex) { - console.log("Attempted to change to slide outside range"); + console.log("Attempted to change to slide outside range (" + slide.toString() + ")"); return; } @@ -47,6 +66,18 @@ function setSlide(slide) { currentSlide = slide; } +function setHeights() { + var firstSlideHeight = slides[0].offsetHeight; + // Set heights (based on height of first slide with 100% width) + for (i = 1; i <= maxIndex; i++) { + var captionHeight = slides[i].getElementsByTagName("figcaption")[0].offsetHeight; + // Set figure height + slides[i].style.height = slides[0].offsetHeight.toString() + "px"; + // Set image height + slides[i].getElementsByTagName("img")[0].style.height = (firstSlideHeight - captionHeight).toString() + "px"; + } +} + function nextSlide() { // Go to the next slide if (currentSlide == maxIndex) { @@ -67,6 +98,11 @@ function prevSlide() { } } +function goToSlide(evt) { + // Go to a slide specified by the event (called when the dots are clicked) + setSlide(evt.currentTarget.slide); +} + function mouseEnter() { // Pause the slideshow clearTimeout(timeout); diff --git a/test-img/1.jpg b/test-img/1.jpg index bab2280..ffff16d 100644 Binary files a/test-img/1.jpg and b/test-img/1.jpg differ diff --git a/test-img/2.jpg b/test-img/2.jpg index b3f3d4c..69dbb01 100644 Binary files a/test-img/2.jpg and b/test-img/2.jpg differ diff --git a/test-img/3.jpg b/test-img/3.jpg index f93f45c..3fdd8f8 100644 Binary files a/test-img/3.jpg and b/test-img/3.jpg differ