How to make prev/next buttons for multiple js slideshow? - javascript

How could I make the slides clickable to navigate forward in the slider? That is how could I make the plusSlides function work for each individual slideshow on one page?
This is the main structure of any slideshow which I could repeat in the same page.
HTLM
<div class="slideshow-container" data-cycle="2000">
<div class="slider fade"><img onclick="plusSlides()" src="assets/img/1.jpg"></div>
<div class="slider fade"><img onclick="plusSlides()" src="assets/img/2.jpg"></div>
<div class="slider fade"><img onclick="plusSlides()" src="assets/img/3.jpg"></div>
<div class="slider fade"><img onclick="plusSlides()" src="assets/img/4.jpg"></div>
<div>
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
</div>
</div>
And this code which works for any slider with the same structure and contained in a div with the class slideshow-container. The slideshows are automatic and have dots.
JS
var slideshowContainers = document.getElementsByClassName("slideshow-container");
for(let s = 0; s < slideshowContainers.length; s++) {
var cont = slideshowContainers[s];
var cycle = slideshowContainers[s].dataset.cycle;
var slides = slideshowContainers[s].querySelectorAll('.slider');
var dots = slideshowContainers[s].querySelectorAll('.dot');
var slideIndex = 0;
showSlides(cont, slides, slideIndex, cycle, dots);
};
var timer = null;
function showSlides(cont, slides, slideIndex, cycle, dots) {
var cont;
slideIndex++;
if (slideIndex > slides.length) {
slideIndex = 1
}
if (slideIndex < 1) {
slideIndex = slides.length
}
for (cont = 0; cont < slides.length; cont++) {
slides[cont].style.display = "none";
}
for (cont = 0; cont < dots.length; cont++) {
dots[cont].className = dots[cont].className.replace(" active", "");
}
slides[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " active";
setTimeout(function() {
showSlides(cont, slides, slideIndex, cycle, dots)
}, cycle);
};

Related

Why won't the first image at first when loading the page? What is wrong with my javaScript?

I am working with wordpress theme twenty twenty-one for the first time and trying to create a slide show of images.. The problem that I am having is that when the page first appears no image is shown. When you click on the button then the first images shows up. Also when you get to the last image I want the first image in the array to show up, but instead no image shows up and you would have to click on the "previous arrow button" that I have created to see the last image again. First time working with the wordpress theme so I am thinking that something is overriding my script or that my script is wrong.
<div>
<img class="exe1-img"
src="https://www.ttttea.co.uk/wp-content/uploads/2021/05/fullsizeoutput_8ca.jpeg" alt="">
<img class="exe1-img" src="https://www.ttttea.co.uk/wp-content/uploads/2021/05/fullsizeoutput_945.jpeg" alt="">
<button class="previous-img" onclick="plusDivs(-1)">❮ </button
button class="next-img" onclick="plusDivs(1)"> ❯</button>
</div>
<script>
let slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function showDivs(n) {
let i;
let x = document.getElementsByClassName("exe1-img");
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";
}
</script>
Had also had an issue with getting the automatic p tags out of the code in wordpress so had to write the script in single line. Apologies for the readability.
After replacing the images (yours were not resolving) and fixing the broken tags (which I think was an artifact of the way it was pasted into your question without using the {} button), it seems to work. Look at the snippet below and see if it's not doing what you want it to.
let slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function showDivs(n) {
let i;
let x = document.getElementsByClassName("exe1-img");
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>
<img class="exe1-img" src="https://images.unsplash.com/photo-1621343498292-eb469c743b25" height='100' alt="">
<img class="exe1-img" height='100' src="https://images.unsplash.com/photo-1621347797284-abb4b9d4ad40" alt="">
<button class="previous-img" onclick="plusDivs(-1)">❮ </button>
<button class="next-img" onclick="plusDivs(1)"> ❯</button>
</div>

Global variable is interfering with other code I would like to put it into these functions as a local variable of make it all into 1 big function

I have A global scope variable that is interfering with the rest of my code I want to be able to implement it within these 3 functions or to turn it all into 1 function that doesn't use global variables but I'm not sure how to achieve this can someone help me. Any help would be appreciated thank you.
var slideIndex = 1;
showSlides(slideIndex);
function plusSlides(n) {
showSlides((slideIndex += n));
}
function currentSlide(n) {
showSlides((slideIndex = n));
}
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";
}
<div>
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<!-- slideshow-container -->
<div class="dot-container-for-slide-banner">
<span class="dot" onclick="currentSlide(1)"></span>
<span class="dot" onclick="currentSlide(2)"></span>
<span class="dot" onclick="currentSlide(3)"></span>
<span class="dot" onclick="currentSlide(4)"></span>
</div>
If you just put the whole code here inside an Immediately Invoked Function Expression (short IIFE), that should prevent any unnecessary global variables:
(() => {
var slideIndex = 1;
showSlides(slideIndex);
// ...
})();
You should also absolutely avoid inline attribute handlers like
onclick="plusSlides(-1)"
and
onclick="currentSlide(1)"
because they require global pollution and have a demented scope chain. Attach the listeners properly using addEventListener instead:
document.querySelector('.prev').addEventListener('click', () => {
plusSlides(-1);
});
document.querySelector('.next').addEventListener('click', () => {
plusSlides(1);
});
document.querySelectorAll('.dot').forEach((span, i) => {
span.addEventListener('click', () => {
currentSlide(i + 1);
});
});

javascript image slideshow plusSlides not functioning

I've setup a way for my family to upload and display photos but I've run into an issue. I've tried to make it into a slideshow. I've tried different methods but haven't found any solution. This is my html:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="css/index2.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="js/display.js"></script>
<script src="js/slideshow.js"></script>
<title>Test Images</title>
</head>
<body>
<div id="slideshow">
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<br>
<div style="text-align:center">
<span class="dot" onclick="currentSlide(1)"></span>
<span class="dot" onclick="currentSlide(2)"></span>
<span class="dot" onclick="currentSlide(3)"></span>
</div>
</body>
</html>
This is my method to put the images into the html:
var folder = "uploads/";
var img = "<img src='";
var imgStyle = "style='width:100%'";
var imgClass = "class='mySlides fade'";
$.ajax({
url : folder,
success : function (data) {
$(data).find("a").attr("href", function (i, val){
if( val.match(/\.(jpe?g|png|gif)$/) ) {
$( "#slideshow" ).append( img + folder + val + "'" + imgStyle + ">");
}
});
}
});
And this is my current slideshow method:
var slideIndex = 1;
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("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";
}
I'm getting this error:
Uncaught ReferenceError: plusSlides is not defined
at HTMLAnchorElement.onclick
I don't have any idea on how to fix this issue.
I came across this problem as well recently! It was answered below in another post here.
The general gist is to use a window load event instead, as HTML can't find the function because it is hidden inside another function. Just change
function plusSlides(n) {
showSlides(slideIndex += n);
}
to
window.plusSlides = function (n) {
showSlides(slideIndex += n);
};`

How do I change a data-tags attribute with an onclick event?

I want the data-tags attribute on the Storepoint map to be "hope-for-men" if the "Healing for Men" div is selected and "betrayal & beyond" if the "Healing for Women" div is selected. I've tried looking at posts with similar goals, but I don't know enough about conditional programming to figure it out.
<div class="spouse-men-box eight columns alpha center">
<div class="groupboxes" onclick="openGroup(event, 'spouse-men-content')">
<h3 class="mB25 white">Healing for Men</h3>
</div>
</div>
<div class="spouse-women-box eight columns omega center">
<div class="groupboxes" onclick="openGroup(event, 'spouse-women-content')">
<h3 class="mB25 white">Healing for Women</h3>
</div>
</div>
<div id="storepoint-container" data-tags="hope for men" data-map-id="158752ddce0df0"></div><script>(function(){var a=document.createElement("script");a.type="text/javascript";a.async=!0;a.src="https://cdn.storepoint.co/api/v1/js/158752ddce0df0.js";var b=document.getElementsByTagName("script")[0];b.parentNode.insertBefore(a,b);}());</script>
<script>// <![CDATA[
function openGroup(evt, groupName) {
var i, groupcontent, groupboxes;
groupcontent = document.getElementsByClassName("groupcontent");
for (i = 0; i < groupcontent.length; i++) {
groupcontent[i].style.display = "none";
}
groupboxes = document.getElementsByClassName("groupboxes");
for (i = 0; i < groupboxes.length; i++) {
groupboxes[i].className = groupboxes[i].className.replace(" active", "");
}
document.getElementById(groupName).style.display = "block";
evt.currentTarget.className += " active";
}
// ]]></script>
You can try:
document.getElementById('storepoint-container')
.setAttribute('data-tags', groupName === 'spouse-men-content' ? 'hope-for-men' : 'betrayal & beyond')
Write a new value to the data-attribute:
document.getElementById('storepoint-container').dataset.tags = 'some new value'
You have to do it in your openGroup function (I've done it in the end, commented everything out that didn't work):
function openGroup(evt, groupName) {
var i, groupcontent, groupboxes;
// not working:
// groupcontent = document.getElementsByClassName("groupcontent");
// for (i = 0; i < groupcontent.length; i++) {
// groupcontent[i].style.display = "none";
// }
groupboxes = document.getElementsByClassName("groupboxes");
for (i = 0; i < groupboxes.length; i++) {
groupboxes[i].className = groupboxes[i].className.replace(" active", "");
}
//not working: document.getElementById(groupName).style.display = "block";
evt.currentTarget.className += " active";
// this is the relevant part:
var storepointContainer = document.getElementById('storepoint-container');
if (groupName === 'spouse-men-content') {
storepointContainer.dataset.tags = 'hope-for-men';
} else {
storepointContainer.dataset.tags = 'betrayal & beyond';
}
}
<div class="spouse-men-box eight columns alpha center">
<div class="groupboxes" onclick="openGroup(event, 'spouse-men-content')">
<h3 class="mB25 white">Healing for Men</h3>
</div>
</div>
<div class="spouse-women-box eight columns omega center">
<div class="groupboxes" onclick="openGroup(event, 'spouse-women-content')">
<h3 class="mB25 white">Healing for Women</h3>
</div>
</div>
<div id="storepoint-container" data-tags="hope for men" data-map-id="158752ddce0df0"></div>

JS onclick not executing for slideshow

I am trying to use W3.CSS Slideshow, the section "Slideshow Indicators".
However I need to create the previous and next buttons dynamically using JS.
But for some reason the prev and next buttons are not working..! (nothing happen onclick)
Here is my code:
HTML Code:
<title>Pre:D</title>
<link rel="stylesheet" href="http://www.w3schools.com/lib/w3.css">
<script src="script.js"></script>
</head>
<body>
<div class="w3-row-padding" style = "width: 800px" id="form">
<div class="mySlides">First Slide</div>
<div class="mySlides">Second Slide</div>
<div class="mySlides">Third Slide</div>
</div>
<div id="toggle" class="w3-center" style = "width: 800px">
</div>
</body>
Js Code:
var slideIndex = 1;
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";
}
x[slideIndex-1].style.display = "block";
}
window.onload=function(){
var dump = document.getElementById("toggle");
var sec = document.createElement("div");
sec.className = "w3-section";
var prev = document.createElement("button");
prev.className = "w3-btn";
prev.addEventListener("click", plusDivs(-1));
prev.innerHTML = "Previous";
var next = document.createElement("button");
next.className = "w3-btn";
next.addEventListener("click", plusDivs(1));
next.innerHTML = "Next";
sec.appendChild(prev);
sec.appendChild(next);
dump.appendChild(sec);
showDivs(slideIndex);
};
The buttons were working when created in the html file, but once I created them using js they got created but the onclick function doesn't work..
In case of passing parameters, bind it like prev.addEventListener("click", function() { plusDivs(-1) });
Here is an Example:
var slideIndex = 1;
function plusDivs(n) {
showDivs(slideIndex += n);
}
function currentDiv(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";
}
window.onload = function() {
var dump = document.getElementById("toggle");
var sec = document.createElement("div");
sec.className = "w3-section";
var prev = document.createElement("button");
prev.className = "w3-btn";
prev.addEventListener("click", function() {
plusDivs(-1)
});
prev.innerHTML = "Previous";
var next = document.createElement("button");
next.className = "w3-btn";
next.addEventListener("click", function() {
plusDivs(1)
});
next.innerHTML = "Next";
sec.appendChild(prev);
sec.appendChild(next);
dump.appendChild(sec);
showDivs(slideIndex);
};
<link href="http://www.w3schools.com/lib/w3.css" rel="stylesheet" />
<div class="w3-row-padding" style="width: 800px" id="form">
<div class="mySlides">First Slide</div>
<div class="mySlides">Second Slide</div>
<div class="mySlides">Third Slide</div>
</div>
<div id="toggle" class="w3-center" style="width: 800px">
</div>

Categories

Resources