initialise listeners in JS, set heights at runtime, add readme
authorAndrew Lorimer <andrew@lorimer.id.au>
Thu, 23 Jun 2022 10:25:33 +0000 (20:25 +1000)
committerAndrew Lorimer <andrew@lorimer.id.au>
Thu, 23 Jun 2022 10:25:33 +0000 (20:25 +1000)
README.md [new file with mode: 0644]
slideshow.css
slideshow.html
slideshow.js
test-img/1.jpg
test-img/2.jpg
test-img/3.jpg
diff --git a/README.md b/README.md
new file mode 100644 (file)
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 `<figure>` consisting of an `<img>` and `<figcaption>`)
+- 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
index 552d5fb7ee1ceb59a560afea9c15c101b8566fdf..3cd4ce095beee09dded899b55c5d0db2da612c39 100644 (file)
@@ -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 {
index a581b1f9e85ec2a7ebccfbe2eb4f10e07b586fd3..88964561d2f7f110e77e7f43cc82d715706c5188 100644 (file)
@@ -6,31 +6,34 @@
 
   <body>
 
-    <div class="slideshow" onmouseenter="mouseEnter()" onmouseleave="mouseLeave()">
+    <div class="slideshow">
+      <div class="slides">
 
-      <figure class="slide">
-        <img src="test-img/1.jpg">
-        <figcaption><span>This is a long caption yeah yeah yeah</figcaption>
-      </figure>
+        <figure class="slide">
+          <img src="test-img/1.jpg">
+          <figcaption>This is a caption</figcaption>
+        </figure>
 
-      <figure class="slide">
-        <img src="test-img/2.jpg">
-        <figcaption><span>Shorter caption</figcaption>
-      </figure>
+        <figure class="slide">
+          <img src="test-img/2.jpg">
+          <figcaption><span>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.</figcaption>
+        </figure>
 
-      <figure class="slide">
-        <img src="test-img/3.jpg">
-        <figcaption><span>Caption 3</figcaption>
-      </figure>
+        <figure class="slide">
+          <img src="test-img/3.jpg">
+          <figcaption>Caption 3</figcaption>
+        </figure>
 
-      <a id="prev" onclick="prevSlide()">&#10094;</a>
-      <a id="next" onclick="nextSlide()">&#10095;</a>
-      <a id="state" onclick="changeState()">&#x23f8;&#xFE0E;</a>
+      </div>
+
+      <a id="prev">&#10094;</a>
+      <a id="next">&#10095;</a>
+      <a id="state">&#x23f8;&#xFE0E;</a>
 
       <div id="controls">
-        <span class="dot" onclick="setSlide(0)"></span>
-        <span class="dot" onclick="setSlide(1)"></span>
-        <span class="dot" onclick="setSlide(2)"></span>
+        <span class="dot"></span>
+        <span class="dot"></span>
+        <span class="dot"></span>
       </div>
 
     </div>
index f73a888142e82afee3b370ec6cc4481908d35feb..80614c9a2562df2ff0194c336883da268f6220d2 100644 (file)
@@ -7,6 +7,9 @@ const STATE_PLAY = "&#x23f5;&#xFE0E;";
 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);
index bab22804e477b3523473355ad7ea21c66fdce5d4..ffff16dc7f575b310dcd4c19aea3948ff5602db8 100644 (file)
Binary files a/test-img/1.jpg and b/test-img/1.jpg differ
index b3f3d4cc5fc4c32118554d5e1a019151b15fffd8..69dbb017a08af79e9a131e90023ba6f2dc64053d 100644 (file)
Binary files a/test-img/2.jpg and b/test-img/2.jpg differ
index f93f45c844f45eb664c7affc92281fac85311e5e..3fdd8f8ffdfe15420df014e5dced25e2cf76b7c5 100644 (file)
Binary files a/test-img/3.jpg and b/test-img/3.jpg differ