javascripthtmlcssslider

JS slideshow that displays caption in two different places in the HTML


I'm trying to create a slideshow gallery using Javascript that displays the caption in two different places in the html - above and below the slideshow. The reason for the redundancy is to incorporate it into a Bootstrap that displays the top caption and hides the lower caption when in mobile view, and vice versa when displayed on larger devices.

I've tried multiple ways to have both captions display simultaneously but the script breaks down when improvising the role of "slide_caption" Id element with function 'showSlides'. How do I apply different ID elements or class element to the demo caption so that it works off the same function?

Here's the complete slideshow: https://codepen.io/canQuackattack/full/RNPaLrV

let slideIndex = 1;
showSlides(slideIndex);

function plusSlides(n) {
  showSlides(slideIndex += n);
}

function currentSlide(n) {
  showSlides(slideIndex = n);
}

function showSlides(n) {
  let i;
  let slides = document.getElementsByClassName("mySlides");
  let dots = document.getElementsByClassName("demo");
  let captionText = document.getElementById("slide_caption");
  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";
  captionText.innerHTML = dots[slideIndex - 1].alt;
}
/* Position the image container (needed to position the left and right arrows) */
.container {
  position: relative;
}

/* Hide the images by default */
.mySlides {
  display: none;
}

/* Add a pointer when hovering over the thumbnail images */
.cursor {
  cursor: pointer;
}

/* Next & previous buttons */
.prev,
.next {
  cursor: pointer;
  position: absolute;
  top: 40%;
  width: auto;
  padding: 16px;
  margin-top: -50px;
  color: white;
  font-weight: bold;
  font-size: 20px;
  border-radius: 0 3px 3px 0;
  user-select: none;
  -webkit-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);
}

/* Number text (1/3 etc) */
.numbertext {
  color: #f2f2f2;
  font-size: 12px;
  padding: 8px 12px;
  position: absolute;
  top: 0;
}

/* Container for image text */
.caption-container {
  text-align: center;
  background-color: #222;
  padding: 2px 16px;
  color: white;
}

.row:after {
  content: "";
  display: table;
  clear: both;
}

/* columns side by side */
.column {
  float: left;
  width: 16.66%;
}

/* Add a transparency effect for thumnbail images */
.demo {
  opacity: 0.6;
}

.active,
.demo:hover {
  opacity: 1;
}
  <h2 style="text-align:center">Slideshow Gallery</h2>

  <div>
    <a class="prev" onclick="plusSlides(-1)">❮</a>
    <a class="next" onclick="plusSlides(1)">❯</a>
  </div>
  <div class="caption-container">
    <p id="slide_caption"></p>
  </div>

  <div class="container">
    <div class="mySlides">
      <div class="numbertext">1 / 3</div>
      <img class="myImages" src="https://www.w3schools.com/howto/img_woods_wide.jpg" alt="The Woods 1" style="width:100%">
    </div>

    <div class="mySlides">
      <div class="numbertext">2 / 3</div>
      <img class="myImages" src="https://www.w3schools.com/howto/img_5terre_wide.jpg" alt="Cinque Terre 1" style="width:100%">
    </div>

    <div class="mySlides">
      <div class="numbertext">3 / 3</div>
      <img class="myImages" src="https://www.w3schools.com/howto/img_mountains_wide.jpg" alt="Mountains and fjords 1" style="width:100%">
    </div>

    <div>
      <a class="prev" onclick="plusSlides(-1)">❮</a>
      <a class="next" onclick="plusSlides(1)">❯</a>
    </div>
    <div class="caption-container">
      <p id="slide_caption"></p>
    </div>

    <div class="row">
      <div class="column">
        <img class="demo cursor" src="https://www.w3schools.com/howto/img_woods_wide.jpg" style="width:100%" onclick="currentSlide(1)" alt="The Woods">
      </div>
      <div class="column">
        <img class="demo cursor" src="https://www.w3schools.com/howto/img_5terre_wide.jpg" style="width:100%" onclick="currentSlide(2)" alt="Cinque Terre">
      </div>
      <div class="column">
        <img class="demo cursor" src="https://www.w3schools.com/howto/img_mountains_wide.jpg" style="width:100%" onclick="currentSlide(3)" alt="Mountains and fjords">
      </div>

    </div>
  </div>


Solution

  • Here is an example of what I think you want:

    // scripts.js
    
    let slideIndex = 1;
    showSlides(slideIndex);
    
    function plusSlides(n) {
      showSlides(slideIndex += n);
    }
    
    function currentSlide(n) {
      showSlides(slideIndex = n);
    }
    
    function showSlides(n) {
      let i;
      let slides   = document.getElementsByClassName("mySlides");
      let dots     = document.getElementsByClassName("demo");
      let captions = document.getElementsByClassName("slide_caption");
    
      if (n > slides.length) {
        slideIndex = 1;
      }
      if (n < 1) {
        slideIndex = slides.length;
      }
    
      // Hide all slides
      for (i = 0; i < slides.length; i++) {
        slides[i].style.display = "none";
      }
      // Remove "active" class from all thumbnails
      for (i = 0; i < dots.length; i++) {
        dots[i].className = dots[i].className.replace(" active", "");
      }
    
      // Show the current slide
      slides[slideIndex - 1].style.display = "block";
      // Highlight the corresponding thumbnail
      dots[slideIndex - 1].className += " active";
    
      // Update both caption <p> tags
      const newText = dots[slideIndex - 1].alt;
      for (i = 0; i < captions.length; i++) {
        captions[i].innerText = newText;
      }
    }
    /* styles.css */
    
    /* Position the image container (needed to position the left and right arrows) */
    .container {
      position: relative;
      max-width: 800px;
      margin: 40px auto;
      background-color: #fff;
      padding: 10px;
      box-shadow: 0 2px 8px rgba(0,0,0,0.1);
      border-radius: 4px;
      
    }
    
    /* Hide the images by default */
    .mySlides {
      display: none;
    }
    
    /* Add a pointer when hovering over the thumbnail images */
    .cursor {
      cursor: pointer;
    }
    
    /* Next & previous buttons */
    .prev,
    .next {
      cursor: pointer;
      position: absolute;
      top: 40%;
      width: auto;
      padding: 16px;
      margin-top: -50px;
      color: white;
      font-weight: bold;
      font-size: 20px;
      border-radius: 0 3px 3px 0;
      user-select: none;
      -webkit-user-select: none;
      background-color: rgba(0, 0, 0, 0.4);
      transition: background-color 0.2s;
    }
    
    /* 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);
    }
    
    /* Number text (1/3 etc) */
    .numbertext {
      color: #f2f2f2;
      font-size: 12px;
      padding: 8px 12px;
      position: absolute;
      top: 0;
    }
    
    /* Container for image text */
    .caption-container {
      text-align: center;
      background-color: #222;
      padding: 2px 16px;
      color: white;
      margin-top: -4px;
      border-radius: 3px;
    }
    
    /* Clearfix for the thumbnail row */
    .row:after {
      content: "";
      display: table;
      clear: both;
    }
    
    /* columns side by side */
    .column {
      float: left;
      width: 16.66%;
    }
    
    /* Add a transparency effect for thumbnail images */
    .demo {
      opacity: 0.6;
    }
    
    .active,
    .demo:hover {
      opacity: 1;
    }
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8" />
      <title>Slideshow Gallery with Top & Bottom Captions</title>
      <link rel="stylesheet" href="styles.css">
    </head>
    <body>
      
      <h2 style="text-align:center">Slideshow Gallery</h2>
      
      <div class="container">
        <!-- ====== TOP CAPTION ====== -->
        <div class="caption-container">
          <p class="slide_caption"></p>
        </div>
        
        <!-- ====== SLIDES ====== -->
        <div class="mySlides">
          <div class="numbertext">1 / 3</div>
          <img class="myImages" src="https://www.w3schools.com/howto/img_woods_wide.jpg"
               alt="The Woods" style="width:100%">
        </div>
    
        <div class="mySlides">
          <div class="numbertext">2 / 3</div>
          <img class="myImages" src="https://www.w3schools.com/howto/img_5terre_wide.jpg"
               alt="Cinque Terre" style="width:100%">
        </div>
    
        <div class="mySlides">
          <div class="numbertext">3 / 3</div>
          <img class="myImages" src="https://www.w3schools.com/howto/img_mountains_wide.jpg"
               alt="Mountains and fjords" style="width:100%">
        </div>
        
        <!-- ====== PREV/NEXT ARROWS (overlayed) ====== -->
        <a class="prev" onclick="plusSlides(-1)">❮</a>
        <a class="next" onclick="plusSlides(1)">❯</a>
        
        <!-- ====== BOTTOM CAPTION ====== -->
        <div class="caption-container">
          <p class="slide_caption"></p>
        </div>
        
        <!-- ====== THUMBNAIL ROW ====== -->
        <div class="row">
          <div class="column">
            <img class="demo cursor" src="https://www.w3schools.com/howto/img_woods_wide.jpg"
                 style="width:100%" onclick="currentSlide(1)" alt="The Woods">
          </div>
          <div class="column">
            <img class="demo cursor" src="https://www.w3schools.com/howto/img_5terre_wide.jpg"
                 style="width:100%" onclick="currentSlide(2)" alt="Cinque Terre">
          </div>
          <div class="column">
            <img class="demo cursor" src="https://www.w3schools.com/howto/img_mountains_wide.jpg"
                 style="width:100%" onclick="currentSlide(3)" alt="Mountains and fjords">
          </div>
        </div>
      </div>
      
      <script src="scripts.js"></script>
    </body>
    </html>