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:
- 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.
- bind an event to viewing an image (scroll \ click)
- 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.
- 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 callsappendChild
on the parent with the firstli
item as a parameter, it will be hidden since it's now the lastli
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.
- 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
JavaScript Beforeunload Detect Refresh Versus Close
How to Resize HTML Canvas Element
Safari: Absolutely Positioned Divs Not Moving When Updated via Dom
Jquery How to Apply CSS to Selected Text
How to Raw Url Encode/Decode in JavaScript and Ruby to Get the Same Values in Both
How to Detect the Screen Resolution with JavaScript
How to Display All Methods of an Object
How to Get Value at a Specific Index of Array in JavaScript
How to Access the Request Body When Posting Using Node.Js and Express
How to Listen/Detect Changes to an Input Value - When the Input Value Is Changed via JavaScript
Opening New Window in HTML for Target="_Blank"
How to Animate the Drawing of Text on a Web Page
Jquery Select Pseudo-Element :After
How to Get the Position of Element Transformed with CSS Rotate
Positioning Multiple, Random Sized, Absolutely Positioned Elements So They Don't Overlap