# Simple JavaScript Slideshow
-This is a very basic slideshow made in JavaScript - no jQuery or other libraries.
+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.
+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)
+- 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>`)
+- 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 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
+- Fix issue where images appear small when advancing slideshow manually without
+ first automatically advancing
* Buttons
*/
-#prev, #next, #state {
+#prev, #next, #state, #expand {
cursor: pointer;
font-weight: bold;
font-size: 1.5em;
padding: 16px;
}
-#state {
+#state, #expand {
width: 1.5em;
height: 1.5em;
+ line-height: 1.5em;
text-align: center;
font-family: monospace;
top: 15px;
- right: 15px;
padding: 4px;
border-radius: 3px;
}
+#state {
+ right: 15px;
+}
+
+#expand {
+ right: calc(15px + 15px + 1.5em);
+}
+
+#expand svg path {
+ fill: #fff;
+}
+
#prev {
left: 0;
border-radius: 0 3px 3px 0;
div.slideshow:hover #prev,
div.slideshow:hover #next,
+div.slideshow:hover #expand,
div.slideshow:hover #state {
/* Show buttons on slideshow hover */
opacity: 100;
background-color: rgba(0,0,0,0.3);
}
-#prev:hover, #next:hover, #state:hover {
+#prev:hover, #next:hover, #expand:hover, #state:hover {
/* Button hover */
background-color: rgba(0,0,0,0.8) !important;
}
</div>
- <a id="prev">❮</a>
- <a id="next">❯</a>
- <a id="state">⏸︎</a>
+ <a id="prev" title="Previous image">❮</a>
+ <a id="next" title="Next image">❯</a>
+ <a id="expand" title="View in new tab">
+ <svg version="1.1" viewBox="0 0 36 36">
+ <path d="m 10,16 2,0 0,-4 4,0 0,-2 L 10,10 l 0,6 0,0 z"></path>
+ <path d="m 20,10 0,2 4,0 0,4 2,0 L 26,10 l -6,0 0,0 z"></path>
+ <path d="m 24,24 -4,0 0,2 L 26,26 l 0,-6 -2,0 0,4 0,0 z"></path>
+ <path d="M 12,20 10,20 10,26 l 6,0 0,-2 -4,0 0,-4 0,0 z"></path>
+ </svg>
+ </a>
+ <a id="state" title="Pause">⏸︎</a>
<div id="controls">
<span class="dot"></span>
let slides = document.getElementsByClassName("slide");
let dots = document.getElementsByClassName("dot");
let stateBtn = document.getElementById("state");
+let expandBtn = document.getElementById("expand");
// Global state
let maxIndex = slides.length - 1;
if (dots.length - 1 != maxIndex) {
console.log("Number of control dots does not match number of slides");
}
+expandBtn.addEventListener("click", expand);
for (i = 0; i <= dots.length - 1; i++) {
dots[i].addEventListener("click", goToSlide);
dots[i].slide = i;
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";
+ slides[i].style.maxHeight = slides[0].offsetHeight.toString() + "px";
// Set image height
- slides[i].getElementsByTagName("img")[0].style.height = (firstSlideHeight - captionHeight).toString() + "px";
+ slides[i].getElementsByTagName("img")[0].style.maxHeight = (firstSlideHeight - captionHeight).toString() + "px";
}
}
// Play immediately despite mouseover
stateBtn.innerHTML = STATE_PAUSE;
timeout = setTimeout(playSlideshow, INTERVAL);
+ stateBtn.title = "Pause";
}
else {
// Pause until user presses play again
clearTimeout(timeout); // make sure timer is stopped
timeout = null;
stateBtn.innerHTML = STATE_PLAY;
+ stateBtn.title = "Play";
}
paused = !paused;
}
+
+function expand() {
+ // Open the image in a new tab
+ window.open(slides[currentSlide].getElementsByTagName('img')[0].src, 'blank');
+}