Need help to incoprate slide-in/out effect HTML/Javascript - javascript

I am having some trouble with some java script code in adding in a slide-in/slide-out effect for a slideshow. Right now, I have the timer working to change pictures every 2 sec. I have the basics of the slide-in and out in CSS just need some help implementing the java script code such that when the picture displays, it slides in and when changing pictures, the current picture slides out. Here is a link to the code pen for my code:
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
if(n > slides.length) {
slideIndex = 1
}
if(n < 1) {
slideIndex = slides.length
}
for(i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slides[slideIndex - 1].style.display = "block";
}
var index = 1;
function runSlideShow()
{
index++;
if(index > 5)
index = 1
currentSlide(index);
setTimeout(runSlideShow, 2000)
}
setTimeout(runSlideShow, 2000)
* {
box-sizing: border-box
}
body {
font-family: nunito sans;
margin: 0
}
.mySlides {
display: none;
}
center > img {
vertical-align: middle;
height: 75vh;
width: auto !important;
}
.slideshow-container {
max-width: 1250px;
position: relative;
margin: auto;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -22px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, add a black background color with a little bit see-through */
.prev:hover,
.next:hover {
background-color: rgba(0, 0, 0, 0.8);
}
/* Caption text */
.text {
color: #FFFFFF;
font-size: 22px;
position: absolute;
margin: 5px 0px;
width: 100%;
text-align: center;
}
/* Number text (1/3 etc) */
.numbertext {
color: #ffffff;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
/* Fading animation */
.slide-in {
-webkit-animation-name: slide-in-right;
-webkit-animation-duration: 1.5s;
animation-name: slide-in-right;
animation-duration: 1.5s;
}
.slide-out {
-webkit-animation-name: slide-out-left;
-webkit-animation-duration: 1.5s;
animation-name: slide-out-left;
animation-duration: 1.5s;
}
#keyframes slide-in {
100% { transform: translateX(0%); }
}
#-webkit-keyframes slide-in {
100% { -webkit-transform: translateX(0%); }
}
#keyframes slide-out {
0% { transform: translateX(0%); }
100% { transform: translateX(-100%); }
}
#-webkit-keyframes slide-out {
0% { -webkit-transform: translateX(0%); }
100% { -webkit-transform: translateX(-100%); }
}
/* On smaller screens, decrease text size */
#media only screen and (max-width: 300px) {
.prev,
.next,
.text {
font-size: 11px
}
}
<div class="slideshow-container" width="100%">
<div class="mySlides slide-in" style="display: block;">
<center>
<div class="numbertext">1 / 6</div>
<img src="https://www.midstory.org/wp-content/uploads/2022/07/theave1896.16.jpeg" style="width:100%">
<div class="text">HR Koopman postcard of 112th and Michigan, facing north, in 1896.</div>
</center>
</div>
<div class="mySlides slide-in" style="display: none;">
<center>
<div class="numbertext">2 / 6</div>
<img src="https://www.midstory.org/wp-content/uploads/2022/07/theave1900.34-1.jpeg" style="width:100%">
<div class="text">HR Koopman photograph of workmen digging sewer system on 111th and Michigan in 1900.</div>
</center>
</div>
<div class="mySlides slide-in" style="display: none;">
<center>
<div class="numbertext">3 / 6</div>
<img src="https://www.midstory.org/wp-content/uploads/2022/07/theave1903.13.jpeg" style="width:100%">
<div class="text">111th and Michigan in 1903 taken by HR Koopman.</div>
</center>
</div>
<div class="mySlides slide-in" style="display: none;">
<center>
<div class="numbertext">4 / 6</div>
<img src="https://www.midstory.org/wp-content/uploads/2022/07/theave1904.18.jpeg" style="width:100%">
<div class="text">HR Koopman postcard showing a busy section of South Michigan Avenue on 113th street in 1904.</div>
</center>
</div>
<div class="mySlides slide-in" style="display: none;">
<center>
<div class="numbertext">5 / 6</div>
<img src="https://www.midstory.org/wp-content/uploads/2022/07/theave1909.12.jpeg" style="width:100%">
<div class="text">Roseland celebrates its 60th anniversary with a huge parade on July 5th, 1909.</div>
</center>
</div>
<div class="mySlides fade" style="display: none;">
<center>
<div class="numbertext">6 / 6</div>
<img src="https://www.midstory.org/wp-content/uploads/2022/07/theave1910.24.jpeg" style="width:100%">
<div class="text">HR Koopman photograph of 115th and Michigan in 1910 showing horse and buggies, a streetcar, and bicycles.</div>
</center>
</div>
</div>
<br>
</div></div>
</div></div>
https://codepen.io/philm001/pen/abYqGew

You can add and remove the animations dynamically toggling classes.
When showing a new slide:
slideToShow.classList.add(“slide-in”)
slideToShow.classList.remove(“slide-out”)
slideToHide.classList.remove(“slide-in”)
slideToHide.classList.add(“slide-out”)
I wrote this answer on mobile so beware of the quotation marks I used. They are not the correct character.

Related

Slideshow code- displaying the first slide and extending the fade duration?

I'm a beginner at coding these more complicated sections that combine HTML, CSS and JS.
I am trying to get the slideshow to display the first slide and extend its duration displaying these slides before they randomly stop. The arrows and the dots work successfully and are shown on the webpage but, the duration of the displaying of slides isn't working and the first slide itself doesn't appear.
WEBSITE PAGE DISPLAY HERE
I have tried extending the duration but I don't know if it needs longer than that or not and I've tried altering the slideshow for statement in the JS code but decided against saving it as it altered the rest of the code.
Below is the picture link of my code which are listed // for different languages I'm using (may require zooming in):
CODE LINK HERE
The code doesn't have any error messages apart from that the dots variable isn't recognised in the JS code.
Thanks so much for your help.
//HTML
<script src="/JavaScript/slideshow.js"></script>
<div class="slideshow-container">
<div class="mySlides fade">
<div class="numbertext">1 / 3</div>
<img src="/Images/CINEMASCREEN.jpg" style="width:100%;">
<div class="text">Caption One</div>
</div>
<div class="mySlides fade">
<div class="numbertext">2 / 3</div>
<img src="/Images/cinemaFood.jpg" style="width:100%;">
<div class="text">Caption Two</div>
</div>
<div class="mySlides fade">
<div class="numbertext">3 / 3</div>
<img src="/Images/cinemakids.jpg" style="width:100%;">
<div class="text">Caption Three</div>
</div>
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<br>
<!-- The dots/circles -->
<div style="text-align:center">
<span class="dot" onclick="currentSlide(1)"></span>
<span class="dot" onclick="currentSlide(2)"></span>
<span class="dot" onclick="currentSlide(3)"></span>
</div>
//CSS
* {box-sizing:border-box}
/* Slideshow container */
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
}
/* Hide the images by default */
.mySlides {
display: hidden;
img {vertical-align: middle;}
}
.prev, .next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 16px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, add a black background color with a little bit see-through */
.prev:hover, .next:hover {
background-color: rgba(0,0,0,0.8);
}
/* Caption text */
.text {
color: #f2f2f2;
font-size: 15px;
padding: 8px 12px;
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
}
/* Number text (1/3 etc) */
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
/* The dots/bullets/indicators */
.dot {
cursor: pointer;
height: 15px;
width: 15px;
margin: 0 2px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.active, .dot:hover {
background-color: #717171;
}
/* Fading animation */
.fade {
-webkit-animation-name: fade;
-webkit-animation-duration: 200s;
animation-name: fade;
animation-duration: 200s;
}
#-webkit-keyframes fade {
from {opacity: .4}
to {opacity: 1}
}
#keyframes fade {
from {opacity: .4}
to {opacity: 1}
}
//JS
var slideIndex = 1;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("dots");
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " active";
}
If you are new to JS and HTML I would recommend trying to use a plugin. Something like Slick Slider would be perfect.
A plugin will be much easier to setup and start using out of the box, it will also be a lot more responsive and functional.
Slick Slider lets you set duration, add or remove navigation dots/arrows, allows looping for the images and lets you choose between swipe and drag. Its also got great documentation and easy to follow examples.
You can learn more and get started here - https://kenwheeler.github.io/slick/
Once you get a feel for things using a plugin, you can start trying to write your own custom carousel.

How would I approach adding automation to a slideshow?

I built a JS slideshow with clickable indicators. I would like for my slideshow to play automatically, while maintaining the functionality of the indicator buttons.
In the code example below, I attempted to add a setTimeout() method to change the image every 2000ms, but it seems to not be working. What would be the best approach to change the JS so I have some automation? I also attempted to use the setInterval method with no luck. I will provide the code below:
Thank you in advance for the help/tips/and advice
var editorialSlideIndex = 1;
showEditorialSlides(editorialSlideIndex);
//Next/previous controls
function plusSlides(n) {
showEditorialSlides(editorialSlideIndex += n);
}
//Thumbnail image controls
function currentSlide(n) {
showEditorialSlides(editorialSlideIndex = n);
}
function showEditorialSlides(n) {
var i;
var slides = document.getElementsByClassName("editorial-slideshow");
var slideDotInd = document.getElementsByClassName("slideDotInd");
if (n > slides.length) {
editorialSlideIndex = 1
}
if (n < 1) {
editorialSlideIndex = slides.length
}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < slideDotInd.length; i++) {
slideDotInd[i].className = slideDotInd[i].className.replace(" active-slider", "");
}
slides[editorialSlideIndex - 1].style.display = "block";
slideDotInd[editorialSlideIndex - 1].className += " active-slider";
setTimeout(showEditorialSlides, 2000); // Change image every 2 seconds
}
/*Slideshow Container */
.editorial-slideshow-container {
padding-top: 15px;
position: relative;
margin: auto;
}
/*Default Hide Images*/
.editorial-slideshow {
display: none;
}
/*Next and previous buttons*/
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -34px;
padding: 10px;
color: white;
font-weight: bold;
font-size: 34px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
background-color: rgba(0, 128, 115, .5);
}
/* Position "next button" */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, background color */
.prev:hover,
.next:hover {
background-color: rgba(0, 128, 115, .8);
}
/* Caption text
.text {
color: #f2f2f2;
font-size: 15px;
padding: 8px 12px;
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
}
Number text (1/3 etc)
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 15;
}
*/
/* The slideslideDotInd/bullets/indicators */
.slideDotInd {
cursor: pointer;
height: 15px;
width: 15px;
margin: 15px 2px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.active-slider,
.slideDotInd:hover {
background-color: #717171;
}
/* Fading animation */
.fade {
-webkit-animation-name: fade;
-webkit-animation-duration: 1.5s;
animation-name: fade;
animation-duration: .25s;
}
#-webkit-keyframes fade {
from {
opacity: .8
}
to {
opacity: 1
}
}
#keyframes fade {
from {
opacity: .8
}
to {
opacity: 1
}
}
#media only screen and (max-width: 425px) {
#CGConainer .banner-title H1 {
line-height: 50px;
}
}
#media only screen and (min-width: 768px) {
.editorial-slideshow-container {
width: 75%;
/*Max width is 576px*/
}
}
#media only screen and (min-width: 1024px) {
.editorial-slideshow-container {
width: 50%;
}
}
<div class="editorial-slideshow-container">
<div class="editorial-slideshow fade">
<img src="https://storage.googleapis.com/img.triggermail.io/hammacher/slider-1.jpg" style="width:100%">
</div>
<div class="editorial-slideshow fade">
<img src="https://storage.googleapis.com/img.triggermail.io/hammacher/slider-2.jpg" style="width:100%">
</div>
<div class="editorial-slideshow fade">
<img src="https://storage.googleapis.com/img.triggermail.io/hammacher/slider-3.jpg" style="width:100%">
</div>
<div class="editorial-slideshow fade">
<img src="https://storage.googleapis.com/img.triggermail.io/hammacher/slider-4a.jpg" style="width:100%">
</div>
<div class="editorial-slideshow fade">
<img src="https://storage.googleapis.com/img.triggermail.io/hammacher/slider-5a.jpg" style="width:100%">
</div>
<div class="editorial-slideshow fade">
<img src="https://storage.googleapis.com/img.triggermail.io/hammacher/slider-6.jpg" style="width:100%">
</div>
<div class="editorial-slideshow fade">
<img src="https://storage.googleapis.com/img.triggermail.io/hammacher/slider-7.jpg" style="width:100%">
</div>
<div class="editorial-slideshow fade">
<img src="https://storage.googleapis.com/img.triggermail.io/hammacher/slider-8.jpg" style="width:100%">
</div>
<div class="editorial-slideshow fade">
<img src="https://storage.googleapis.com/img.triggermail.io/hammacher/slider-9.jpg" style="width:100%">
</div>
<div class="editorial-slideshow fade">
<img src="https://storage.googleapis.com/img.triggermail.io/hammacher/slider-10.jpg" style="width:100%">
</div>
<p class="prev" onclick="plusSlides(-1)">‹</p>
<p class="next" onclick="plusSlides(1)">›</p>
</div>
<div style="text-align:center">
<span class="slideDotInd" onclick="currentSlide(1)"></span>
<span class="slideDotInd" onclick="currentSlide(2)"></span>
<span class="slideDotInd" onclick="currentSlide(3)"></span>
<span class="slideDotInd" onclick="currentSlide(4)"></span>
<span class="slideDotInd" onclick="currentSlide(5)"></span>
<span class="slideDotInd" onclick="currentSlide(6)"></span>
<span class="slideDotInd" onclick="currentSlide(7)"></span>
<span class="slideDotInd" onclick="currentSlide(8)"></span>
<span class="slideDotInd" onclick="currentSlide(9)"></span>
<span class="slideDotInd" onclick="currentSlide(10)"></span>
</div>
It's such a small change.
The way you called setTimeout is wrong.
function showEditorialSlides(n) {
var i;
var slides = document.getElementsByClassName("editorial-slideshow");
var slideDotInd = document.getElementsByClassName("slideDotInd");
if (n > slides.length) {
editorialSlideIndex = 1
}
if (n < 1) {
editorialSlideIndex = slides.length
}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < slideDotInd.length; i++) {
slideDotInd[i].className = slideDotInd[i].className.replace(" active-slider", "");
}
slides[editorialSlideIndex - 1].style.display = "block";
slideDotInd[editorialSlideIndex - 1].className += " active-slider";
setTimeout(() => showEditorialSlides(editorialSlideIndex = (n+1)), 2000); // Change image every 2 seconds
}
And that was the reason your function was being called incorrectly.
EDIT: I forgot to mention the reason. There was no way JavaScript knew what parameters you were passing to the function when you're trying to recurse.
You can try it out in the fiddle

Shadow Root getElementsByClassName

I am using LitElement to create custom Web Components. I am fairly new at it and decided to try making image slideshow. I used W3Schools slideshow as reference
while modifying it to work as LitElement.
The problem is, that when I am trying to use document.getElementByClassName I am not getting anything. I am familiar with this issue since I am working with Shadow DOM so I changed it to this.shadowRoot.getElementsByClassName. Unfortunately, I get told that what I am trying to use is not a function. How Do I get elements by class name when I am working with LitElement and shadow dom? In case you want to see how my component looks like, here is the code:
import { LitElement, html} from '#polymer/lit-element';
class ImageGalleryElement extends LitElement {
static get properties() { return {
slideIndex: { type: Number },
}};
constructor(){
super();
this.slideIndex=1;
this.showSlides(this.slideIndex);
}
// Next/previous controls
plusSlides(n) {
this.showSlides(this.slideIndex += n);
}
// Thumbnail image controls
currentSlide(n) {
this.showSlides(this.slideIndex = n);
}
showSlides(n) {
var i;
console.dir(this.shadowRoot);
var slides = this.shadowRoot.getElementsByClassName("mySlides");
console.dir(slides);
var dots = this.shadowRoot.getElementsByClassName("dot");
if (n > slides.length) {this.slideIndex = 1}
if (n < 1) {this.slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[this.slideIndex-1].style.display = "block";
dots[this.slideIndex-1].className += " active";
}
render(){
return html`
<style>
* {box-sizing:border-box}
/* Slideshow container */
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
}
/* Hide the images by default */
.mySlides {
display: none;
}
/* Next & previous buttons */
.prev, .next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 16px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, add a black background color with a little bit see-through */
.prev:hover, .next:hover {
background-color: rgba(0,0,0,0.8);
}
/* Caption text */
.text {
color: #f2f2f2;
font-size: 15px;
padding: 8px 12px;
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
}
/* Number text (1/3 etc) */
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
/* The dots/bullets/indicators */
.dot {
cursor: pointer;
height: 15px;
width: 15px;
margin: 0 2px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.active, .dot:hover {
background-color: #717171;
}
/* Fading animation */
.fade {
-webkit-animation-name: fade;
-webkit-animation-duration: 1.5s;
animation-name: fade;
animation-duration: 1.5s;
}
#-webkit-keyframes fade {
from {opacity: .4}
to {opacity: 1}
}
#keyframes fade {
from {opacity: .4}
to {opacity: 1}
}
</style>
<!-- Slideshow container -->
<div class="slideshow-container">
<!-- Full-width images with number and caption text -->
<div class="mySlides fade">
<div class="numbertext">1 / 3</div>
<img src="../../img/img-snow-wide" style="width:100%">
<div class="text">Caption Text</div>
</div>
<div class="mySlides fade">
<div class="numbertext">2 / 3</div>
<img src="../../img/img-nature-wide" style="width:100%">
<div class="text">Caption Two</div>
</div>
<div class="mySlides fade">
<div class="numbertext">3 / 3</div>
<img src="../../img/img-mountains-wide" style="width:100%">
<div class="text">Caption Three</div>
</div>
<!-- Next and previous buttons -->
<a class="prev" #click="${this.plusSlides(-1)}" >❮</a>
<a class="next" #click="${this.plusSlides(1)}">❯</a>
</div>
<br>
<!-- The dots/circles -->
<div style="text-align:center">
<span class="dot" #click="${this.currentSlide(1)}"></span>
<span class="dot" #click="${this.currentSlide(2)}"></span>
<span class="dot" #click="${this.currentSlide(3)}"></span>
</div>
`;
}
}
// Register the element with the browser
customElements.define('image-gallery-element', ImageGalleryElement);
The getElementsByClassName() method works only on a HTML Document or element.
The shadowRoot is a Document Fragment by inheritance, not a Document nor a HTML element.
Instead you should use querySelectorAll().
It's the same behavior for:
getElementsByTagName()
getElementsByClassName()
Note 1
getElementById() is not available on (in memory) nodes created with document.createElement
Test Selector Methods: https://jsfiddle.net/WebComponents/9yrtn8vb/
Note 2
Be aware slotted content is not moved to shadowDOM, it remains in ligthDOM
When you move Elements from lightDOM (in main DOM) to shadowRoot,
the Live Nodelist will be emptied
let pieces = document.getElementsByTagName("[TAGNAME here]");
console.warn(tags);// lists all tags
this.shadowRoot.append(...this.children);
console.warn(tags);// empty
LitElement also offers its own convenient decorators to access nodes: #query, #queryAll, and #queryAsync decorators
But for sure I understand if you want to stay vanilla :)

object.onclick is not working

I've been searching through forums for the past few hours and can't seem to figure out why I my onclick method isn't working properly.
For context, I'm trying to get this code to output something in the console when a button is clicked.
document.getElementsByClassName("next").onclick = function test() {
console.log("hello");
}
Here are my next/previous buttons:
<!-- Next and previous buttons -->
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
The code I'm using was referenced from w3schools, although I modified it slightly. Here's the entirety of it:
HTML
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="script.js"></script>
<link rel="stylesheet" type="text/css" href="style.css" />
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
</head>
<body onload="getInformation(), showSlides()">
<!-- Slideshow container -->
<div class="slideshow-container">
<!-- Full-width images with number and caption text -->
<div class="mySlides">
<div class="numbertext">1 / 5</div>
<img src="https://images.pexels.com/photos/104827/cat-pet-animal-domestic-104827.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"
style="width:100%">
<div class="text"></div>
</div>
<div class="mySlides">
<div class="numbertext">2 / 5</div>
<img src="https://images.pexels.com/photos/730896/pexels-photo-730896.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"
style="width:100%">
<div class="text"></div>
</div>
<div class="mySlides">
<div class="numbertext">3 / 5</div>
<img src="https://images.pexels.com/photos/57416/cat-sweet-kitty-animals-57416.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"
style="width:100%">
<div class="text"></div>
</div>
<div class="mySlides">
<div class="numbertext">4 / 5</div>
<img src="https://images.pexels.com/photos/569170/pexels-photo-569170.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"
style="width:100%">
<div class="text"></div>
</div>
<div class="mySlides">
<div class="numbertext">5 / 5</div>
<img src="https://images.pexels.com/photos/271955/pexels-photo-271955.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"
style="width:100%">
<div class="text"></div>
</div>
<!-- Next and previous buttons -->
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<br>
<!-- The dots/circles -->
<div style="text-align:center">
<span class="dot" onclick="currentSlide(1)"></span>
<span class="dot" onclick="currentSlide(2)"></span>
<span class="dot" onclick="currentSlide(3)"></span>
<span class="dot" onclick="currentSlide(4)"></span>
<span class="dot" onclick="currentSlide(5)"></span>
</div>
</body>
</html>
CSS
html {
background-color: black;
}
body {
padding-top: 50px;
}
* {box-sizing:border-box}
/* Slideshow container */
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
}
/* Hide the images by default */
.mySlides {
display: none;
}
/* Next & previous buttons */
.prev, .next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 16px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, add a black background color with a little bit see-through */
.prev:hover, .next:hover {
background-color: rgba(0,0,0,0.8);
}
/* Caption text */
.text {
color: #f2f2f2;
font-size: 15px;
padding: 8px 12px;
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
}
/* Number text (1/3 etc) */
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
/* The dots/bullets/indicators */
.dot {
cursor: pointer;
height: 15px;
width: 15px;
margin: 0 2px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.active, .dot:hover {
background-color: #717171;
}
/* Fading animation */
.fade {
-webkit-animation-name: fade;
-webkit-animation-duration: 1.5s;
animation-name: fade;
animation-duration: 1.5s;
}
#-webkit-keyframes fade {
from {opacity: .4}
to {opacity: 1}
}
#keyframes fade {
from {opacity: .4}
to {opacity: 1}
}
Javascript
var slideIndex = 1;
showSlides(slideIndex);
function getInformation() {
console.log(document.getElementsByClassName("prev")[0].innerHTML);
console.log(document.getElementsByClassName("next")[0].innerHTML);
}
function updateInformation() {
console.log("The current slide is: " + slideIndex);
// console.log("Value in array is: " + [slideIndex-1]);
}
document.getElementsByClassName("next") = function test() {
console.log("hello");
}
// Next/previous controls
function plusSlides(n) {
showSlides(slideIndex += n);
}
// Thumbnail image controls
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("dot");
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " active";
updateInformation();
}
If anyone could help I would greatly appreciate it. Let me know if you need any more information.
The getElementsBy* methods return HTMLCollections, which can be difficult to work with - and also, they're collections, not individual elements, so you'd have to select an individual element from it first before attaching a listener to the element. Consider using querySelectorAll instead, which returns a static NodeList - unlike an HTMLCollection, it can be iterated over directly, it won't change while it's being iterated over, and it's much more flexible.
Or if you're only selecting a single element, use querySelector instead:
document.querySelector('.next').addEventListener('click', function test() {
console.log("hello");
});
Avoid inline handlers (which are as bad as eval) and onclick, which restricts you to one listener of a type per element - use addEventListener instead.

Disabling/hiding slideshow arrows on first/last slides

I am using a slideshow based on w3school's sample. I'd like to disable or hide the previous arrow on the first slide and next arrow on the last slide.
I believe I need to edit this JavaScript to include an if else clause (if first slide, hide .prev button, else show), but the problem is my lack of understanding. I have a basic understanding of JavaScript, but going deep into the math side (n or i values) is confusing me, and I haven't yet learned jQuery.
function plusSlides(n) {
showSlides(slideIndex += n);
}
Can anyone help me with the code, and also explain what the code would mean in layman's terms?
For easy reference, the code pulled straight from the example is:
var slideIndex = 1;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("dot");
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " active";
}
/* Slideshow container */
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
}
/* Next & previous buttons */
.prev, .next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 16px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, add a black background color with a little bit see-through */
.prev:hover, .next:hover {
background-color: rgba(0,0,0,0.8);
}
/* Caption text */
.text {
color: #f2f2f2;
font-size: 15px;
padding: 8px 12px;
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
}
/* Number text (1/3 etc) */
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
/* The dots/bullets/indicators */
.dot {
cursor:pointer;
height: 13px;
width: 13px;
margin: 0 2px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.active, .dot:hover {
background-color: #717171;
}
/* Fading animation */
.fade {
-webkit-animation-name: fade;
-webkit-animation-duration: 1.5s;
animation-name: fade;
animation-duration: 1.5s;
}
#-webkit-keyframes fade {
from {opacity: .4}
to {opacity: 1}
}
#keyframes fade {
from {opacity: .4}
to {opacity: 1}
}
<div class="slideshow-container">
<div class="mySlides fade">
<div class="numbertext">1 / 3</div>
<img src="img1.jpg" style="width:100%">
<div class="text">Caption Text</div>
</div>
<div class="mySlides fade">
<div class="numbertext">2 / 3</div>
<img src="img2.jpg" style="width:100%">
<div class="text">Caption Two</div>
</div>
<div class="mySlides fade">
<div class="numbertext">3 / 3</div>
<img src="img3.jpg" style="width:100%">
<div class="text">Caption Three</div>
</div>
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<br>
<div style="text-align:center">
<span class="dot" onclick="currentSlide(1)"></span>
<span class="dot" onclick="currentSlide(2)"></span>
<span class="dot" onclick="currentSlide(3)"></span>
</div>
I'm not quite sure what part of the code you need an explanation for. In general terms it's just adding or substracting from the slide index, adjusting the index when it "overflows" or "underflows" and hiding the slides with a different index.
If you don't want to show first and last arrows you can just add code like
var prevArrow = document.getElementsByClassName('prev');
var nextArrow = document.getElementsByClassName('next');
prevArrow[0].style.display = "block";
nextArrow[0].style.display = "block";
if (slideIndex === 1) prevArrow[0].style.display = "none";
if (slideIndex === slides.length) nextArrow[0].style.display = "none";
That code just "hides" the "prev arrow when you're in the first slide and the "next" arrow when you're in the last", you can test it in the w3school page and it works. I hope that helps
There's a lot of room for optimization

Categories