I have a slideshow in JS and html which works fine until I use a variable stored in localStorage to define which slide to start from when the page refresh/reload.
What works:
- after the page has reloaded, the slideshow starts from the desired slide;
- after the page has reloaded and after the first command forward, the slideshow begins to work correctly.
What does not work:
- after the page has reloaded, moving the slideshow forward for the first time always makes the slideshow begins from the first slide;
- after the page has reloaded, moving the slideshow backward for the first time always makes the variable in the local storage undefined and the slides disappear.
I think the issue is with the showSlides(), but I cannot understand what it is.
Here is my code so far:
// Set local storage
var slideIx = localStorage.getItem('slideIndex');
if (slideIx === null) {
slideIx = 1;
}
var slideIndex = slideIx;
showSlides(slideIndex);
// Next/previous controls
function plusSlides(n) {
showSlides(slideIndex += n);
localStorage.setItem('slideIndex', slideIndex);
console.log(localStorage.getItem('slideIndex'));
}
// Thumbnail image controls
function currentSlides(n) {
showSlides(slideIndex = n);
localStorage.setItem('slideIndex', slideIndex);
console.log(localStorage.getItem('slideIndex'));
}
// Show slides
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";
}
// Arrows control
document.onkeydown = function(e) {
e = e || window.event;
if (e.keyCode == '37') {
e.preventDefault();
plusSlides(-1); //left <- show Prev image
} else if (e.keyCode == '39') {
e.preventDefault();
plusSlides(1); // right -> show next image
}
};
Thank you very much for any hint you might have(!).
I think the issue is that you need to convert string to number before you operate with it. The value retrieved from localStorage is always of a String type, while you expect number in your code. Try this:
var slideIx = Number(localStorage.getItem('slideIndex') || 1);
(then next check for null is not needed).
I succeeded the slideShow to show the last picture after refreshing the page by the next code (you can see it here https://jsfiddle.net/mu9otwcy/1/):
var myIndex;
if(localStorage.getItem('slideIx') === null){
myIndex = 0;
}
else{
myIndex = localStorage.getItem('slideIx') -1;
}
console.log(myIndex);
carousel();
function carousel() {
var i;
var x = document.getElementsByClassName("mySlides");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
myIndex++;
console.log(myIndex);
if (myIndex > x.length) {
myIndex = 1;
}
x[myIndex-1].style.display = "block";
var slideIx = localStorage.setItem('slideIx',myIndex);
setTimeout(carousel, 3000);
}
Related
I want to build something like this: https://jenniferlynnwagner.com/spanish360/story_html5.html (just for reference). I have images with content, now I want to display them on the screen and when the user clicks on next or previous button, able to do so. So, how can I achieve this thing in my project using JavaScript and Spring boot (backend)?
Below is the script to handle current, next and previous slide.
window.addEventListener('DOMContentLoaded', event => {
// Toggle the side navigation
const sidebarToggle = document.body.querySelector('#sidebarToggle');
if (sidebarToggle) {
// Uncomment Below to persist sidebar toggle between refreshes
// if (localStorage.getItem('sb|sidebar-toggle') === 'true') {
// document.body.classList.toggle('sb-sidenav-toggled');
// }
sidebarToggle.addEventListener('click', event => {
event.preventDefault();
document.body.classList.toggle('sb-sidenav-toggled');
localStorage.setItem('sb|sidebar-toggle', document.body.classList.contains('sb-sidenav-toggled'));
});
}
});
var slide_index = 1;
displaySlides(slide_index);
//chapter1-image 1-182
//chapter 2-image-1-127
//chapter 3-image 1-56
//chapter 4-image 1-42
//chapter 5-image 1-67
function nextSlide(n) {
document.getElementById("slide-img").src="img/slider-2.jpg"
playAudio(slide_index);
}
function playAudio(number) {
var audioElement = document.getElementById("my_audio");
audioElement.pause();
audioElement.currentTime = 0;
audioElement.src = "audio/" + number + ".mp3";
audioElement.load();
audioElement.play();
}
function currentSlide(n) {
displaySlides(slide_index = n);
}
function displaySlides(n) {
var i;
var slides = document.getElementsByClassName("showSlide");
if (n > slides.length) { slide_index = 1 }
if (n < 1) { slide_index = slides.length }
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slides[slide_index - 1].style.display = "block";
}
i have make it an slider with 2 image, the first is Gotrade and second Midas. I want when im on first slide to not display the left arrow and when im on second the right arrow to not be displayed.
if (firstSlide.classList.contains('active-slide')) {
buttonLeft.style.display = 'none';
buttonRight.style.display = 'flex';
} else if (secondSlide.classList.contains('second-slide')) {
buttonLeft.style.display = 'flex';
buttonRight.style.display = 'none';
}
I tried this but doesn't work.
Here is the image for reference
https://i.stack.imgur.com/lTXdt.png
https://i.stack.imgur.com/82clB.png
Codepen: https://codepen.io/andrei-nistor/pen/ZEeeGEG
There are several things wrong with your code. For example, you're checking for a classname called active-slide, but nothing in your code sets a class with that name. If you're copying and pasting code from other sources without taking some time to understand it, it may be impossible to debug.
Instead of checking for the existence of a class that doesn't exist, you can instead check for which slide number you're on, and check if you're on the first or last slide. You also need to run this code after slide transitions, not once at the end of your program as you've shown in the Codepen. Here's an example of the working Javascript checking for slideIndex instead of a class:
var slideIndex = 1;
let firstSlide = document.querySelector('.first-slide');
let secondSlide = document.querySelector('.second-slide');
let buttonLeft = document.querySelector('.prev');
let buttonRight = document.querySelector('.next');
showSlides(slideIndex);
// 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");
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 = "flex";
if (slideIndex === 1) {
buttonLeft.style.display = 'none';
buttonRight.style.display = 'flex';
} else if (slideIndex === slides.length) {
buttonRight.style.display = 'none';
buttonLeft.style.display = 'flex';
}
}
I don't know javascript and could use some help. I have a lightbox that pops up but I can't change the slide index # - it works if it's not hidden. is there a way to fix it? I have 10 images numbered 1-10 for the light box and looking for the first one to pop up to be #10 instead of #1
EXAMPLE:
https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_js_lightbox - trying to change the "currentSlider" to show in descending order when popped up
<script>
// Open the Modal
function openModal() {
$('#myModal').toggleClass('mod-act');
$("#popOverlay").fadeIn();
}
// Close the Modal
function closeModal() {
$('#myModal').removeClass('mod-act');
$("#popOverlay").fadeOut();
}
var slideIndex = 3;// MY ISSUE STARTS HERE
showSlides(slideIndex);
// 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("demo");
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";
}
</script>
If you can't work with the hidden element, so you can set opacity = 0 instead of display none and set position absolute to make them place in the same line.
Hi I would like to display one javascript slider but if the size is less that 825px the fonction to be disable I created one code but they don't work. I search here but i dont found any answer about that.
here my code
$(window).ready(function() {
var wi = $(window).width();
$(window).resize(function() {
var wi = $(window).width();
if (wi < 825){
} else {
// Slide function
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";
}
}
});
});
thank you for any help the slide function work perfect but i dont arrive to detect the windows size.
Define a function to do the slide, add a condition to return
function doSlide() {
if (window.innerWidth < 825) {
return
}
// Slide function
...your code
}
As people suggested, call it directly. Attach resize event if you want.
$(window).ready(function() {
doSlide()
window.addEventListener('resize', doSlide)
}
I'm having a hard time coming up with a solution on how to clear setInterval when clicking on a specific button(with class "next"). My code is listed bellow, and I'm just starting to learn js and jquery so it's probably in a bad shape.
<script>
var slideIndex = 1;
showSlides(slideIndex);
function plusSlides(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";
}
$(document).ready(function(){
function playslider(){
$('.next').trigger('click');
var x = setTimeout(function(){playslider()}, 5000);
}
playslider(); <!--To loop-->
});
</script>
Also if you wouldn't mind helping how can I make the first click to occur 5 seconds after the page is loaded.
Edit: To elaborate more, so you have bigger understanding of what I'm doing and with what I need help.
I am creating a simple automatic picture Slideshow, that has a Next and Previous button. I want to cancel the setInterval(missused with setTimout), when pressing on either Next or Previous button. And I'm having a hard time figuring out where to put the code and how it should look like to clear setInterval time, while simultaneously going to the next picture.
You mix jQuery and DOM in an unhealthy manner var slides = $(".mySlides");
You are looking for clearInterval if you use setInterval and clearTimeout if you use setTimeout
To delay execution use the page load:
var tId ;
function playslider(){
$('.next').trigger('click');
}
$(function() {
tId = setInterval(playslider,5000); // can be stopped with clearInterval(tId);
});
You are actually using setTimeout, not setInterval.
You can cancel timeout using clearTimeout(id)
You can also use setInterval instead:
var slideIndex = 1;
showSlides(slideIndex);
function plusSlides(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";
}
$(document).ready(function(){
var intervalId = null;
function enablePlayback(){
if(intervalId == null) {
setInterval(function() {
$('.next').trigger('click'); // you should implement this differently, as this is bad practice.
}, 5000);
}
}
function disablePlayback() {
if(intervalId != null) {
clearInterval(intervalId);
intervalId = null;
}
}
enablePlayback(); <!--To loop-->
$('#ButtonToDisable').click(function() { disablePlayback(); });
$('#ButtonToEnable').click(function() { enablePlayback(); });
});