I've made a slideshow in native javascript but the next and previous buttons don't work. Also the pagination dots should follow the respective slide.
When pressing the next button, the next slide should display and so on. In devTools it shows the first slide has the style set to display and the first dot has the active class added but when pressing the next/prev buttons nothing happens.
Here is my code:
window.onload = function() {
document.getElementById("nextSlide").addEventListener("click",nextSlide());
document.getElementById("prevSlide").addEventListener("click",prevSlide());
};
var slideIndex = 0;
function nextSlide() {
var slideList = document.getElementsByClassName("imgSlide");
var dots = document.getElementsByClassName("dots");
slideIndex += 1;
if (slideIndex >= slideList.length) {
slideIndex = 0;
}
for(var i = 0; i < slideList.length; i++) {
slideList[i].style.display = "none";
}
for(var d = 0; d < dots.length; d++) {
dots[d].classList.remove("active");
}
slideList[slideIndex].style.display = "block";
dots[slideIndex].classList.add("active");
return false;
}
function prevSlide() {
var slideList = document.getElementsByClassName("imgSlide");
var dots = document.getElementsByClassName("dots");
slideIndex -= 1;
if (slideIndex < 0) (slideList.length - 1);
for(var i = 0; i < slideList.length; i++) {
slideList[i].style.display = "none";
}
for(var d = 0; d < dots.length; d++) {
dots[d].classList.remove("active");
}
slideList[slideIndex].style.display = "block";
dots[slideIndex].classList.add("active");
}
And my HTML
<div id="slides-container">
<ul class="slides">
<li class="imgSlide"><img
src="/BackOffice/viagens_header_images/blobid1508696899148.jpg"
alt="Alpine
Scenery" /></li>
<li class="imgSlide"><img
src="/BackOffice/viagens_header_images/blobid1509065118446.jpg"
alt="Kalte
Rinne" /></li>
<li class="imgSlide"><img
src="/BackOffice/viagens_header_images/blobid1508696913346.jpg"
alt="Adiltzgraben" /></li>
</ul>
<div class="controls"><button type="button" id="prevSlide" role="button">
</button>
<ul class="dot-navigation">
<li class="dots"></li>
<li class="dots"></li>
<li class="dots"></li>
</ul>
<button type="button" id="nextSlide" role="button"></button></div>
</div>
Listener parameter in addEventListener for a named function must be a function name without quotes and brackets:
document.getElementById("nextSlide").addEventListener("click", nextSlide);
document.getElementById("prevSlide").addEventListener("click", prevSlide);
And also another small bug. Instead of the line if (slideIndex < 0) (slideList.length - 1);
must be:
if (slideIndex < 0) {
slideIndex = slideList.length;
}
window.onload = function() {
document.getElementById("nextSlide").addEventListener("click", nextSlide);
document.getElementById("prevSlide").addEventListener("click", prevSlide);
};
var slideIndex = 0;
function nextSlide() {
var slideList = document.getElementsByClassName("imgSlide");
var dots = document.getElementsByClassName("dots");
slideIndex += 1;
if (slideIndex >= slideList.length) {
slideIndex = 0;
}
for (var i = 0; i < slideList.length; i++) {
slideList[i].style.display = "none";
}
for (var d = 0; d < dots.length; d++) {
dots[d].classList.remove("active");
}
slideList[slideIndex].style.display = "block";
dots[slideIndex].classList.add("active");
return false;
}
function prevSlide() {
var slideList = document.getElementsByClassName("imgSlide");
var dots = document.getElementsByClassName("dots");
slideIndex -= 1;
if (slideIndex < 0) {
slideIndex = slideList.length - 1;
}
for (var i = 0; i < slideList.length; i++) {
slideList[i].style.display = "none";
}
for (var d = 0; d < dots.length; d++) {
dots[d].classList.remove("active");
}
slideList[slideIndex].style.display = "block";
dots[slideIndex].classList.add("active");
}
.imgSlide:not(:first-child) {
display: none;
}
.slides {
list-style-type: none;
}
<div id="slides-container">
<ul class="slides">
<li class="imgSlide"><img src="http://via.placeholder.com/350x150" alt="350x150"></li>
<li class="imgSlide"><img src="http://via.placeholder.com/300x200" alt="300x200"></li>
<li class="imgSlide"><img src="http://via.placeholder.com/400x300" alt="400x300"></li>
</ul>
<div class="controls">
<button type="button" id="prevSlide" role="button">Back</button>
<ul class="dot-navigation">
<li class="dots"></li>
<li class="dots"></li>
<li class="dots"></li>
</ul>
<button type="button" id="nextSlide" role="button">Next</button></div>
</div>
Related
I'm having a problem returning elements from my object array.
I have a slideshow in which an image (photo of the book) and a text (title of the book) must appear.
For the creation of the slideshow I have no problems because I am using querySelectors as shown in the code below.
The problem lies in showing the images with their titles.
In the first part of the code I have an array of objects that gives me the total number of elements present and based on this I create the slideshow (to create the scroll points and the "container" to contain the images) and then subsequently I call the function myFunction with id argument to return the single element (identified by an id).
What I notice is that the urls with the ids are returned to me, but the url with that id is returned multiple times (so it gets copied) and not just once as expected; I should have only 4 url in total (each with the specific id of the element, since only 4 elements). The same happens when I return the array of objects, it does not return 4 but many more.
Referring to url1:
If I click on the arrows of the slideshow I only receive one image, the other images I do not receive.
I have no mistakes.
var slideIndex = 1;
var outerXmlhttp = new XMLHttpRequest();
var url = "https://wjko8t4509.execute-api.us-east-2.amazonaws.com/books";
outerXmlhttp.onreadystatechange = function () {
var innerXmlhttp;
if (this.readyState == 4 && this.status == 200) {
var allbook = JSON.parse(this.responseText);
for (var i = 0, len = allbook.Items.length; i < len; i++) {
id = allbook.Items[i].id
showSlides(slideIndex);
myFunction(id);
}
}
};
outerXmlhttp.open("GET", url, true);
outerXmlhttp.send();
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides fade");
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";
}
function myFunction(id) {
var url1 = "https://wjko8t4509.execute-api.us-east-2.amazonaws.com/books/" + id;
innerXmlhttp = new XMLHttpRequest();
innerXmlhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var myArr = JSON.parse(this.responseText);
document.getElementById("img").src = "book_img/" + myArr.Item.immagine;
document.getElementById("title").innerHTML = `${myArr.Item.titolo}`;
}
};
innerXmlhttp.open("GET", url1, true);
innerXmlhttp.send();
}
<div class="slideshow-container" id="slideshow">
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<br>
<div id="punt" style="text-align:center">
</div>
EDIT
Array allbook with error:
Several things I noticed:
Doesn't define the id
As you state, the data structure from api will look like {"Item":{"marca":"Love","titolo":"You will be missed indefinitely","id":"123456","immagine":"ind.jpg","data":"27/11/2021"}}, but are trying to loop over all the item inside item which will be incorrect, you should loop over allbook.
It should be allbook[i].Items.length instead of allbook.Items.length
var slideIndex = 1;
let id;
var outerXmlhttp = new XMLHttpRequest();
var url = "https://wjko8t4509.execute-api.us-east-2.amazonaws.com/books";
outerXmlhttp.onreadystatechange = function() {
var innerXmlhttp;
if (this.readyState == 4 && this.status == 200) {
var allbook = JSON.parse(this.responseText);
for (var i = 0, len = allbook.length; i < len; i++) {
id = allbook[i].Items.id
document.querySelector('.slideshow-container').innerHTML += `
<div class="mySlides fade">
<div class="numbertext">${i+1}/${allbook[i].Items.length}</div>
<img id="img" src onerror="this.onerror=null; this.src=myFunction(${id});" style="width:100%">
<div class="text" id="title" onclick="myFunction(${id})"></div>
</div>`;
document.querySelector('#punt').innerHTML += `
<span class="dot" onclick=currentSlide(${i+1})></span>`;
myFunction(id);
}
showSlides(0);
}
};
outerXmlhttp.open("GET", url, true);
outerXmlhttp.send();
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides fade");
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";
}
function myFunction(id) {
var url1 = "https://wjko8t4509.execute-api.us-east-2.amazonaws.com/books/" + id;
innerXmlhttp = new XMLHttpRequest();
innerXmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myArr = JSON.parse(this.responseText);
document.getElementById("img").src = "book_img/" + myArr.Item.immagine;
document.getElementById("title").innerHTML = `${myArr.Item.titolo}`;
}
};
innerXmlhttp.open("GET", url1, true);
innerXmlhttp.send();
}
<div class="slideshow-container" id="slideshow">
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<br>
<div id="punt" style="text-align:center">
</div>
I'm trying to add a play and pause button to my image viewer. I have next and prev buttons working fine but would love a play and pause button integrated into my JavaScript.
Can anyone please help out?
Here is a working demo via link Demo
Script:
<div class="w3-container">
</div>
<div class="w3-content" style="max-width:800px">
<img class="mySlides" src="http://www.chorleyweather.com/forecast-charts/ecmwfcharts/na500hpa_1.png" style="width:95%"></li>
<img class="mySlides" src="http://www.chorleyweather.com/forecast-charts/ecmwfcharts/na500hpa_2.png" style="width:95%"></li>
</div>
<div class="w3-section">
<button class="w3-btn" onclick="plusDivs(-1)"><h6> Prev Image<h6/></button>
<button class="w3-btn" onclick="plusDivs(1)"><h6>Next Image<h6/> </button><h6/>
</div>
</div>
<script>
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function currentDiv(n) {
showDivs(slideIndex = n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
if (n > x.length) {slideIndex = 1}
if (n < 1) {slideIndex = x.length}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" w3-red", "");
}
x[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " w3-red";
}
window.onload = function() {
var image = document.getElementById("img");
function updateImage() {
image.src = image.src.split("?")[0] + "?" + new Date().getTime();
}
setInterval(updateImage, 1000);
}
</script>
A way would be with a boolean which determines if it should be playing or not, and a button that changes the value of that boolean.
button:
<button id="playpause"></button>
updated window.onload = function
window.onload = function() {
var image = document.getElementById("img");
var playing = true;
function updateImage() {
if (playing) {
image.src = image.src.split("?")[0] + "?" + new Date().getTime();
}
}
var playpause = document.getElementById("playpause");
playpause.onclick = function() {
if (playing) {
playing = false;
} else {
playng = true;
}
};
setInterval(updateImage, 1000);
}
Didn't try this, but it should do the trick.
I wanna add 2 slideshow in one single webpages so this is the code for 1 slide show
<script>
var slideIndex = 0;
var slides = document.getElementsByClassName("mySlides1");
showSlides();
function showSlides() {
var i;
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slideIndex++;
if (slideIndex> slides.length) {slideIndex = 1}
slides[slideIndex-1].style.display = "block";
setTimeout(showSlides, 3000); // Change image every 5 seconds
}
function currentSlide(no) {
var i;
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slideIndex = no;
slides[no-1].style.display = "block";
function plusSlides(n) {
var newslideIndex = slideIndex + n;
if(newslideIndex < 6 && newslideIndex > 0){
currentSlide(newslideIndex);
}
}
</script>
then I wanted to add another slideshow so I add mySlides2
var slides = document.getElementsByClassName("mySlides1", "mySlides2");
but it's not working .
Get your slide elements into two HTMLCollections then combine them into one array.
var slide1 = document.getElementsByClassName("mySlides1");
var slide2 = document.getElementsByClassName("mySlides1");
var slides = [];
for(var i = 0; i < slide1.length; i++){
slides[i] = slide1[i];
}
for(var length = slide1.length, i = length; i < slide2.length+length; i++ ){
slides[i] = slide2[i - length];
}
//showSlides();
I am trying to make a slideShow kind of thing but I have problems with margin and/or position absolute when I try to reposition buttons When I write:
<style="position: absolute; left: somepx; etc:"></style>
or
<div style="position: absolute; left: somepx; etc:"></div>
my code that is in div breaks For example My button has this code :
<button class="slide" onclick="plusDivs(-1)"
style="margin: 265px;">❮</button>
I have jsCode here :
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
if (n > x.length) {slideIndex = 1}
if (n < 1) {slideIndex = x.length} ;
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[slideIndex-1].style.display = "block";
}
I ALSO have some text They are in class: mySlides
When I run the code The button is repositioned but it doesnt work
Same thing with margin
Help please
It's kinda hard to tell from the code you posted, where the mistake is because it's not included. Please check these things:
The script must be loaded before the html if you want to use onclick
Your Slide-Elements don't have the class mySlides (maybe you gave it accidentaly to the container)
Alternatively you can use an Event on the button instead, because the script you posted works fine:
document.getElementById('btn').addEventListener('click', function() {
plusDivs(-1);
});
Here is a complete Snipptet
var slideIndex = 1;
showDivs(slideIndex);
document.getElementById('btn').addEventListener('click', function() {
plusDivs(-1);
});
function plusDivs(n) {
showDivs(slideIndex += n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
if (n > x.length) {
slideIndex = 1
}
if (n < 1) {
slideIndex = x.length
};
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[slideIndex - 1].style.display = "block";
}
<div style="position: absolute; left: 50px;"></div>
<div class="mySlides">1</div>
<div class="mySlides">2</div>
<div class="mySlides">3</div>
<button id="btn" class="slide" style="margin: 8px;">❮</button>
to start things of I want to mention that I am very new at this and probably very bad and I have tried for weeks now, searched answers and so on and just couldn't implement something proper in my code. I want to simply pause / resume a slide animation. I managed to make most of it work, but the problem is the setInterval. mine is set to 10s. I have a fading-in-out animation that lasts also 10 secs. If i pause lets say after 5 secs and then resume, the animation will have 10 extra seconds adding up to 15, after which it will change the slide abruptly and I want a smooth transition.
What I could think of is to save the elapsed time from the interval at the moment of pausing and then subtract that value from the total time of the interval and set it for the remaining part. Problem is i don't know how to put that into code. :/
var slideIndex = 1;
var myIndex = 0;
var myVar;
var playing = true;
var pauseButton = document.getElementById("pause");
var y = document.getElementsByClassName("mySlides");
var k;
var div = document.getElementsByClassName("stuff");
var globaltime = 10000;
var slideInterval = setInterval(carousel, globaltime);
var milisec;
function plusDivs(n) {
showDivs(slideIndex += n);
}
function currentDiv(n) {
showDivs(slideIndex = n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
if (n > x.length) {slideIndex = 1}
if (n < 1) {slideIndex = x.length}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" white", "");
}
x[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " white";
}
function carousel() {
var i;
var x = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
myIndex++;
if (myIndex > x.length) {myIndex = 1}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" white", "");
}
x[myIndex-1].style.display = "block";
dots[myIndex-1].className += " white";
}
function pauseSlideshow(){
pauseButton.innerHTML = '►';
playing = false;
t = slideInterval;
clearInterval(slideInterval);
for (k = 0; k < div.length; k++) {
div[k].className = div[k].className.replace(" running", " paused");
}
}
function playSlideshow(){
pauseButton.innerHTML = '❙❙';
playing = true;
slideInterval = setInterval(carousel, globaltime);
for (k = 0; k < div.length; k++) {
div[k].className = div[k].className.replace(" paused", " running");
}
}
function stop(){
if(playing){
pauseSlideshow();
}
else {
playSlideshow();
}
}
carousel();
timer();
showDivs(slideIndex);
Thank you very much in advance for your time, patience and understanding.