Multiple Slideshows on One Page Makes the First One Not Work Anymore

Multiple slideshows on one page makes the first one not work anymore

I've created a solution here:

var sliderObjects = [];createSliderObjects();
function plusDivs(obj, n) { var parentDiv = $(obj).parent(); var matchedDiv; $.each(sliderObjects, function(i, item) { if ($(parentDiv[0]).attr('id') == $(item).attr('id')) { matchedDiv = item; return false; } }); matchedDiv.slideIndex=matchedDiv.slideIndex+n; showDivs(matchedDiv, matchedDiv.slideIndex);}
function createSliderObjects() { var sliderDivs = $('.slider'); $.each(sliderDivs, function(i, item) { var obj = {}; obj.id = $(item).attr('id'); obj.divContent = item; obj.slideIndex = 1; obj.slideContents = $(item).find('.mySlides'); showDivs(obj, 1); sliderObjects.push(obj); });}
function showDivs(divObject, n) { debugger; var i; if (n > divObject.slideContents.length) { divObject.slideIndex = 1 } if (n < 1) { divObject.slideIndex = divObject.slideContents.length } for (i = 0; i < divObject.slideContents.length; i++) { divObject.slideContents[i].style.display = "none"; } divObject.slideContents[divObject.slideIndex - 1].style.display = "block";}
<link href="http://www.w3schools.com/lib/w3.css" rel="stylesheet"/><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><h2 class="w3-center">Manual Slideshow</h2>
<div class="w3-content w3-display-container slider" id="div1"> <img class="mySlides" src="https://i.imgur.com/eLarayS.jpg" style="width:100%"> <img class="mySlides" src="https://i.imgur.com/xpOiMWh.jpg" style="width:100%"> <img class="mySlides" src="https://i.imgur.com/lgcC8Y5.jpg" style="width:100%"> <img class="mySlides" src="http://i.imgur.com/ufmiVTQ.jpg" style="width:100%">
<a class="w3-btn-floating w3-display-left" onclick="plusDivs(this,-1)">❮</a> <a class="w3-btn-floating w3-display-right" onclick="plusDivs(this,1)">❯</a></div>
<div class="w3-content w3-display-container slider" id="div2"> <img class="mySlides" src="https://i.imgur.com/eLarayS.jpg" style="width:100%"> <img class="mySlides" src="https://i.imgur.com/xpOiMWh.jpg" style="width:100%"> <img class="mySlides" src="https://i.imgur.com/lgcC8Y5.jpg" style="width:100%"> <img class="mySlides" src="http://i.imgur.com/ufmiVTQ.jpg" style="width:100%">
<a class="w3-btn-floating w3-display-left" onclick="plusDivs(this, -1)">❮</a> <a class="w3-btn-floating w3-display-right" onclick="plusDivs(this, 1)">❯</a></div>

Multiple slideshows on one page not work anymore

the functions in your top <script> have the same names as in your bottom <script> that is why they get overridden. Essentially, both sliders call the bottom definition of the functions.
A quick and dirty fix is just renaming the bottom ones:

var slideIndex -> var slideIndex2

function plusDivs(n) -> function plusDivs2(n)

function currentDiv(n) -> function currentDiv2(n)

function showDivs(n) -> function showDivs2(n)

Remember to update every mention of slideIndex inside your renamed functions to slideIndex2 as well.

Also, in your mySlides2 html, change the onclick= to match your new function names.

To summarize:
-Rename everything in your second <script> tag by adding "2" at the end

-Then make your second slider html call the renamed functions instead of the original ones.

EDIT:

I just noticed, you need to rename the css class demo in the bottom slider html markup as well, or your bullets won't display correctly.

How do I make multiple slideshows in the same html document?

Assign an id to each slide container and provide that to all of the slideshow functions. In addition, use that same object to track the current slideshow index.

var slideshow1 = document.getElementById("slideshow1");slideshow1.currentSlideIndex = 1;showSlides(slideshow1.currentSlideIndex, slideshow1);
var slideshow2 = document.getElementById("slideshow2");slideshow2.currentSlideIndex = 1;showSlides(slideshow2.currentSlideIndex, slideshow2);

function plusSlides(n, slideshow) { showSlides(slideshow.currentSlideIndex += n, slideshow);}
function currentSlide(n, slideshow) { showSlides(slideshow.currentSlideIndex = n, slideshow);}
function showSlides(n, slideshow) {

var i; var slides = slideshow.getElementsByClassName("mySlides"); var dots = slideshow.getElementsByClassName("dot"); if (n > slides.length) {slideshow.currentSlideIndex = 1} if (n < 1) {slideshow.currentSlideIndex = 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[slideshow.currentSlideIndex-1].style.display = "block"; dots[slideshow.currentSlideIndex-1].className += " active";}
* {box-sizing:border-box}body {font-family: Verdana,sans-serif;margin:0}.mySlides {display:none}
/* Slideshow container */.slideshow-container { max-width: 1000px; 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;}
/* 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}}
/* On smaller screens, decrease text size */@media only screen and (max-width: 300px) { .prev, .next,.text {font-size: 11px}}
<div id="slideshow1" class="slideshow-container">
<div class="mySlides fade"> <div class="numbertext">1 / 3</div> <img src="img_nature_wide.jpg" style="width:100%"> <div class="text">Caption Text</div></div>
<div class="mySlides fade"> <div class="numbertext">2 / 3</div> <img src="img_fjords_wide.jpg" style="width:100%"> <div class="text">Caption Two</div></div>
<div class="mySlides fade"> <div class="numbertext">3 / 3</div> <img src="img_mountains_wide.jpg" style="width:100%"> <div class="text">Caption Three</div></div>
<a class="prev" onclick="plusSlides(-1,slideshow1)">❮</a><a class="next" onclick="plusSlides(1, slideshow1)">❯</a>

<div style="text-align:center"> <span class="dot" onclick="currentSlide(1, slideshow1)"></span> <span class="dot" onclick="currentSlide(2, slideshow1)"></span> <span class="dot" onclick="currentSlide(3, slideshow1)"></span> </div></div><br>

<div id="slideshow2" class="slideshow-container">
<div class="mySlides fade"> <div class="numbertext">1 / 3</div> <img src="img_nature_wide.jpg" style="width:100%"> <div class="text">Caption Text</div></div>
<div class="mySlides fade"> <div class="numbertext">2 / 3</div> <img src="img_fjords_wide.jpg" style="width:100%"> <div class="text">Caption Two</div></div>
<div class="mySlides fade"> <div class="numbertext">3 / 3</div> <img src="img_mountains_wide.jpg" style="width:100%"> <div class="text">Caption Three</div></div>
<a class="prev" onclick="plusSlides(-1, this.parentNode)">❮</a><a class="next" onclick="plusSlides(1, this.parentNode)">❯</a>

<div style="text-align:center"> <span class="dot" onclick="currentSlide(1, slideshow2)"></span> <span class="dot" onclick="currentSlide(2, slideshow2)"></span> <span class="dot" onclick="currentSlide(3, slideshow2)"></span> </div></div><br>

More than one slideshows on one page

Updated your code and 3 slideshows can run easily.

You just have to adapt your js code (like I did);

  • Add class name of the 3rd slideshow,
  • Call showSlides(1, id);.

var slideIndex = [1,1,1];var slideId = ["slide", "slide2", "slide3"]showSlides(1, 0);showSlides(1, 1);showSlides(1, 2);
function plusSlides(n, no) { showSlides(slideIndex[no] += n, no);}
function showSlides(n, no) { var i; var x = document.getElementsByClassName(slideId[no]); if (n > x.length) {slideIndex[no] = 1} if (n < 1) {slideIndex[no] = x.length} for (i = 0; i < x.length; i++) { x[i].style.display = "none"; } x[slideIndex[no]-1].style.display = "block"; }
* {box-sizing: border-box}.mySlides{display: none}img {vertical-align: middle;}
/* Slideshow container */.slideshow-container { max-width: 800px; position: relative;}
/* Next & previous buttons */.prev, .next { cursor: pointer; position: absolute; top: 4%; 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; height:100%; width:49.5%;}
/* Position the "next button" to the right */.next { right: 0; border-radius: 3px 0 0 3px;}
/* On hover, add a grey background color */.prev:hover, .next:hover { color: black;}
<h2 style="text-align:center">Multiple Slideshows</h2>
<p>Slideshow 1:</p><div class="slideshow-container"> <div class="mySlides slide"> <img src="https://picsum.photos/150/150" style="width:100%"> </div>
<div class="mySlides slide"> <img src="https://picsum.photos/150/151" style="width:100%"> </div>
<div class="mySlides slide"> <img src="https://picsum.photos/151/150" style="width:100%"> </div>
<a class="prev" onclick="plusSlides(-1, 0)">prev</a> <a class="next" onclick="plusSlides(1, 0)">next</a></div>
<p>Slideshow 2:</p><div class="slideshow-container"> <div class="mySlides slide2"> <img src="https://picsum.photos/152/150" style="width:100%"> </div>
<div class="mySlides slide2"> <img src="https://picsum.photos/150/152" style="width:100%"> </div>
<div class="mySlides slide2"> <img src="https://picsum.photos/150/154" style="width:100%"> </div>
<a class="prev" onclick="plusSlides(-1, 1)">prev</a> <a class="next" onclick="plusSlides(1, 1)">next</a></div>
<p>Slideshow 3:</p><div class="slideshow-container"> <div class="mySlides slide3"> <img src="https://picsum.photos/152/151" style="width:100%"> </div>
<div class="mySlides slide3"> <img src="https://picsum.photos/151/152" style="width:100%"> </div>
<div class="mySlides slide3"> <img src="https://picsum.photos/151/154" style="width:100%"> </div>
<a class="prev" onclick="plusSlides(-1, 2)">prev</a> <a class="next" onclick="plusSlides(1, 2)">next</a></div>

Loading multiple slideshows one at a time

One option is to use the JQuery LazyLoad plugin.

Another, more hands-on approach would be something along the lines of:

  1. On first load, create tags for all images. For loaded images provide src attribute, for later-loaded images provide the src in a different attribute.
  2. bind an event to viewing an image (scroll \ click)
  3. when the event fires, find the next image, get the alternative src attribute and plug it into the src attribute.

previous button causing slideshow to disappear

this works for me: (you may have forgotten a dot in the second slider). Check out this Fiddle: https://jsfiddle.net/prtuxoxx/

<div class="slideshow-container">
<a class="prev" ></a>
<a class="next"></a>

<div class="mySlides fade">
<img src="http://www.w3schools.com/howto/img_mountains_wide.jpg" style="width:100%">
</div>

<div class="mySlides fade">
<img src="http://www.w3schools.com/howto/img_fjords_wide.jpg" style="width:100%">
</div>

<div class="mySlides fade">
<img src="http://www.w3schools.com/howto/img_nature_wide.jpg" style="width:100%">
</div>

<div class="mySlides fade">
<img src="http://placehold.it/1000x350" style="width:100%">
</div>

<div style="text-align:center">
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
</div>
</div>
<div class="text-container">
<div class="project-title">Rust Belt Riders</div>
<div class="project-description">Identity for Rust Belt Riders, a waste management and composting company from Cleveland. </div>
</div>

<br>

<div class="slideshow-container">
<a class="prev" ></a>
<a class="next"></a>

<div class="mySlides fade">
<img src="http://www.w3schools.com/howto/img_mountains_wide.jpg" style="width:100%">
</div>

<div class="mySlides fade">
<img src="http://www.w3schools.com/howto/img_fjords_wide.jpg" style="width:100%">
</div>

<div class="mySlides fade">
<img src="http://www.w3schools.com/howto/img_nature_wide.jpg" style="width:100%">
</div>

<div class="mySlides fade">
<img src="http://placehold.it/1000x350" style="width:100%">
</div>

<div style="text-align:center">
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
</div>
</div>
<div class="text-container">
<div class="project-title">Rust Belt Riders</div>
<div class="project-description">Identity for Rust Belt Riders, a waste management and composting company from Cleveland. </div>
</div>

and JS:

(function() {

init(); //on page load - show first slide, hidethe rest

function init() {

parents = document.getElementsByClassName('slideshow-container');

for (j = 0; j < parents.length; j++) {
var slides = parents[j].getElementsByClassName("mySlides");
var dots = parents[j].getElementsByClassName("dot");
slides[0].classList.add('active-slide');
dots[0].classList.add('active');
}
}

dots = document.getElementsByClassName('dot'); //dots functionality

for (i = 0; i < dots.length; i++) {

dots[i].onclick = function() {

slides = this.parentNode.parentNode.getElementsByClassName("mySlides");

for (j = 0; j < this.parentNode.children.length; j++) {
this.parentNode.children[j].classList.remove('active');
slides[j].classList.remove('active-slide');
if (this.parentNode.children[j] == this) {
index = j;
}
}
this.classList.add('active');
slides[index].classList.add('active-slide');

}
}
//prev/next functionality
links = document.querySelectorAll('.slideshow-container a');

for (i = 0; i < links.length; i++) {
links[i].onclick = function() {
current = this.parentNode;

var slides = current.getElementsByClassName("mySlides");
var dots = current.getElementsByClassName("dot");
curr_slide = current.getElementsByClassName('active-slide')[0];
curr_dot = current.getElementsByClassName('active')[0];
curr_slide.classList.remove('active-slide');
curr_dot.classList.remove('active');
if (this.className == 'next') {
console.log('next ', curr_slide);
if (curr_slide.nextElementSibling.classList.contains('mySlides')) {
curr_slide.nextElementSibling.classList.add('active-slide');
curr_dot.nextElementSibling.classList.add('active');
} else {
slides[0].classList.add('active-slide');
dots[0].classList.add('active');
}

}

if (this.className == 'prev') {
console.log('previous ', curr_slide);
if (curr_slide.previousElementSibling.classList.contains('mySlides')) {
curr_slide.previousElementSibling.classList.add('active-slide');
curr_dot.previousElementSibling.classList.add('active');
} else {
slides[slides.length - 1].classList.add('active-slide');
dots[slides.length - 1].classList.add('active');
}

}

}

}
})();

How to add a second slideshow on the same webpage

Well, part of the key is to parameterize all of the required details - that is, don't hard-code things like the output container's id or that of the target image element if you decide to use a single image and change it's source.

  1. Some approaches use an unordered-list and set it (with css) so only the first item is visible. Changing slides then becomes a matter of moving the li items around inside their container. I.e if one calls appendChild on the parent with the first li item as a parameter, it will be hidden since it's now the last li item and the 2nd item will now be the first and this will be the one displayed.

While the second approach is a little more straight forward, the 1st has the benefits of (0) not needing to know or care how many images there are - you simply move the first li item to be the last, or move the last one to be first and, (1) all the images are loaded at the start, so you don't get a small delay as each slide is shown for the first time and loaded.


  1. Other approaches change the src of an image element.

I've utilized the second here. I've not bothered with prev/next buttons - this may mean this answer is beyond you at the moment. I would add prev/next functions inside the startSlideshow function and return the function itself - i.e return this;, rather than the id of the timer (which is to allow it to be stopped via clearInterval)

JS

function newEl(tag){return document.createElement(tag)}
function byId(id){return document.getElementById(id)}

window.addEventListener('load', onDocLoaded, false);

function onDocLoaded(evt)
{
var slideshow1TimerId = startSlideshow( ['uqrsGpO.jpg', 'vote-pedro.jpg'], 'slide1', 3000 );
var slideshow2TimerId = startSlideshow( ['zS0lOud.jpg', 'tree.png', 's13.bmp'], 'slide2', 1000 );
}

function startSlideshow(imgNameArray, idOfContainer, msPerSlide)
{
var container = byId(idOfContainer);
var tgtImgElem = newEl('img');
container.appendChild(tgtImgElem);

var timerId = setInterval(setSlideImg, msPerSlide);
var slideIndex = 0;
var numSlides = imgNameArray.length;

function setSlideImg()
{
tgtImgElem.src = imgNameArray[slideIndex];
slideIndex++;
if (slideIndex >= numSlides)
slideIndex = 0;
}
return timerId;
}

CSS

#slide1 img, #slide2 img
{
height: 128px;
}

HTML

<div id='slide1'></div>
<div id='slide2'></div>


Related Topics



Leave a reply



Submit