function giving undefined error in JQuery - javascript

I am trying to integrate a slider into my application.
I am referring this w3schools sample.
But for some reason whenever the page loads the images comes for a second then disappears and when i click on arrow or dots i am getting function undefined error like below.
Uncaught ReferenceError: plusSlides is not defined
at HTMLAnchorElement.onclick (details.html:1)
Any help would be appreciated, thanks in advance...!!!
Please find my code below.
<!DOCTYPE html>
<html>
<head>
<!-- Meta -->
<meta charset="utf-8">
<title>Xylem</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="author" content="Samuel Norton">
<!-- Styles -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="css/reset.css">
<link rel="stylesheet" href="css/style.css">
<link href='http://fonts.googleapis.com/css?family=Lato:300,400,700,900|Raleway:400,300,700,600,900' rel='stylesheet' type='text/css'>
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.1/jquery-ui.js"></script>
<script src="http://code.jquery.com/color/jquery.color-2.1.0.min.js"></script>
<style>
* {box-sizing:border-box}
.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: 15px;
width: 15px;
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}
}
</style>
</head>
<body class="bgColor">
<div class="container-fluid">
<div>
<div>
<div>
<div class="productContent">
<a class="nextlinkProcuct"> &#8592 GO BACK</a>
<div class="row containerDiv">
<div class="col-md-12 pd10-top pd10-bottom">
<div class="slideshow-container">
<!-- Next and previous buttons -->
</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>
<span class="dot" onclick="currentSlide(4)"></span>
<span class="dot" onclick="currentSlide(5)"></span>
</div>
</div>
<div class="col-md-12 title">360 View</div>
<div style="width: 400px;" class="col-md-4">
<script src='https://vizor.io/static/scripts/vizor-360-embed.js' data-vizorurl='https://vizor.io/embed/anamikabadal/americanorthcarolinamorrisville'></script>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
$( document ).ready(function() {
var i;
var detailsDataObj = {
"Title":"XYLEM WATER SOLUTIONS INDIA PVT LTD.",
"Description":"This page will aim to list all the high level modules and the functionality (use cases) for each module. Each module can be considered an EPIC and sub-bulleted use case as super-stories. Each Super-story will have stories that will be tracked in Jira and used for Sprint planning. This page will only list epics and super - stories.",
"sliderImage":["img1.jpg","img2.jpg","img3.jpg","img4.jpg","img5.jpg"],
"Image360":"images/testing.jpeg"
}
var titleDiv = '<div class="title col-md-12 pd10-top pd10-bottom centerText">'+ detailsDataObj.Title + '</div>'; // Create text with HTML
$(".containerDiv").append(titleDiv); // Append new elements
var pageDesc = '<div class="discription col-md-12 pd10-top pd10-bottom">'+ detailsDataObj.Description + '</div>';
$(".containerDiv").append(pageDesc); // Append new elements
var prevArrow = '<a class="prev" onclick="plusSlides(-1)">❮</a>';
var nextArrow = '<a class="next" onclick="plusSlides(1)">❯</a>';
for(i=0;i<detailsDataObj.sliderImage.length;i++){
var slideContainer = '<div class="mySlides fade">';
var img = '<img height="300" ';
img+='src="'+detailsDataObj.sliderImage[i]+'"';
img+='/>';
slideContainer+=img;
slideContainer+='</div>';
$('.slideshow-container').append(slideContainer);
}
$('.slideshow-container').append(prevArrow,nextArrow);
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";
}
});
</script>
</body>
</html>

You're trying to call functions globally from your HTML document:
onclick="plusSlides(-1)"
But those functions are defined in a closed scope inside another function:
$(document).ready(function() {
//...
function plusSlides(n) {
showSlides(slideIndex += n);
}
//...
});
Nothing defined inside that anonymous function() {} passed to the document.ready handler will be visible outside that function.
You can assign the functions to the window object instead:
$(document).ready(function() {
//...
window.plusSlides = function (n) {
showSlides(slideIndex += n);
};
//...
});
Or define the functions outside of that scope:
$(document).ready(function() {
//...
});
function plusSlides(n) {
showSlides(slideIndex += n);
}
//...
Your other functions, references to those functions, etc. may also need to be adjusted for the same reasons. Things outside a function can be accessed from inside of it, but not the other way around.

This is a classic scoping issue.
plusSlides is defined inside the $.ready(function) which has it's own scope and is not accessible at window level. Easy fix for you is to rewrite it like so:
window.plusSlides = function(n) {
showSlides(slideIndex += n)
}
So plusSlides is now a function accessible at window scope, however, the content of the function also is a closure with access to the scope from the
$.ready(function).

Related

How to make an automatic slideshow with buttons?

I created a automatic slideshow by using html , css and javascript but the next/previous and dot buttons are not working. When I made them work , slideshow becomes unautomatic. I added buttons to its cshtml file so nothing's missing. CSS file works perfectly as well. What is missing in my code ? Any help will be appreciated.
Javascript Code
let slideIndex = 0;
showSlides();
function showSlides() {
let i;
let slides = document.getElementsByClassName("mySlides");
let dots = document.getElementsByClassName("dot");
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slideIndex++;
if (slideIndex > slides.length) { slideIndex = 1 }
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";
setTimeout(showSlides, 5000); // Change image every 2 seconds
}
var responsiveSlider = function () {
var slider = document.getElementById("slider");
var sliderWidth = slider.offsetWidth;
var slideList = document.getElementById("slideWrap");
var count = 1;
var items = slideList.querySelectorAll("li").length;
var prev = document.getElementById("prev");
var next = document.getElementById("next");
window.addEventListener('resize', function () {
sliderWidth = slider.offsetWidth;
});
var prevSlide = function () {
if (count > 1) {
count = count - 2;
slideList.style.left = "-" + count * sliderWidth + "px";
count++;
}
else if (count = 1) {
count = items - 1;
slideList.style.left = "-" + count * sliderWidth + "px";
count++;
}
};
var nextSlide = function () {
if (count < items) {
slideList.style.left = "-" + count * sliderWidth + "px";
count++;
}
else if (count = items) {
slideList.style.left = "0px";
count = 1;
}
};
next.addEventListener("click", function () {
nextSlide();
});
prev.addEventListener("click", function () {
prevSlide();
});
setInterval(function () {
nextSlide()
}, 5000);
};
window.onload = function () {
responsiveSlider();
}
#using SliderBannerProject.Model.Entity
#model List<Table_Slider>
#{
Layout = "~/Views/Shared/TestLayout.cshtml";
}
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link href="~/Content/mystyle.css" rel="stylesheet" />
<script defer src="~/Content/Script.js"></script>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
</head>
<body>
<div class="slideshow-container">
<!-- Full-width images with number and caption text -->
#foreach (var item in Model)
{
<div class="mySlides w3-animate-fading">
<div class="numbertext">#item.ID</div>
<img src="#item.SliderPhoto" style="width:100%" />
<br />
<br />
<div class="text" id="text1" >#item.SliderInfo1</div>
<br />
<br />
<div class="text" id="update">
<p style="margin-bottom:-50px" >
<a href="/Test/UpdateInfo/#item.ID" id="update1">
Update Slider
</a>
</p>
</div>
</div>
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
}
</div>
<br>
</body>
<!-- The dots/circles -->
<br />
<div style="text-align:center">
#foreach (var item in Model)
{
<span class="dot" onclick="currentSlide(#item.ID)"></span>
}
</div>
<br />
<div style="text-align:center">
Add New Slider Photo
</div>
</html>
* {
box-sizing: border-box
}
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
animation: slide 10s infinite;
}
.mySlides {
display: none;
background-repeat: no-repeat;
background-size: cover;
width: 100%;
height: 80vh;
transition: all .2s ease-in-out;
animation: slide 10s infinite;
}
#text1 {
font-size: 100px;
font-display:swap;
font-style:oblique;
color:gray;
}
#update {
background-color: transparent;
border: none;
color: black;
padding: 16px 32px;
text-align: center;
font-size: 25px;
margin: 4px 2px;
opacity: 0.6;
transition: 0.3s;
display: inline-block;
text-decoration: none;
cursor: pointer;
}
#update1 {
color: black;
}
.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;
user-select: none;
}
/* 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);
}
.text {
color: #f2f2f2;
font-size: 15px;
padding: 8px 12px;
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
}
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
.dot {
cursor: pointer;
height: 15px;
width: 15px;
margin: 0 2px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition: background-color 5s ease;
}
.active, .dot:hover {
background-color: #717171;
}
.fade {
animation-name: fade;
animation-duration: 4s;
animation: slide 10s infinite;
}
#keyframes fade {
from {
opacity: 10
}
to {
opacity: 10
}
}
let slideIndex = 1;
let i;
let slides = document.getElementsByClassName("slides");
let dots = document.getElementsByClassName("dot");
auto();
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
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 auto() {
slideIndex++;
if (slideIndex > slides.length) {slideIndex = 1}
showSlides(slideIndex);
setTimeout(auto, 10000);
}
Try this i found that on youtube, here is the link.

How to fill the mobile window with image?

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Document</title>
<link href="index.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="index.js"></script>
</head>
<body>
<div class="slideshow-container">
<div class="mySlideDiv fade active">
<img src="bg.jpg">
</div>
<div class="mySlideDiv fade">
<img src="lemon.jpg">
</div>
<div class="mySlideDiv fade">
<img src="pear.webp">
</div>
<a class="prev" onclick="prevSlide()">❮</a>
<a class="next" onclick="nextSlide()">❯</a>
</div>
</body>
</html>
body{
margin: 0;
}
/* Slideshow container */
.slideshow-container {
/*max-width: 1440px;*/
position: relative;
margin: auto;
margin-left: 0%;
margin-top: 0%;
}
/* effect */
.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}
}
/* Next & previous buttons */
.prev, .next {
cursor: pointer;
position: absolute;
top: 45%;
width: auto;
padding: 16px;
margin-top: -22px;
color: red;
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);
}
img{
width:100%;
height: 30%important;
}
$(document).ready(function () {
$(".mySlideDiv").not(".active").hide();
setInterval(nextSlide, 4000);
});
function prevSlide() {
$(".mySlideDiv").hide();
var allSlide = $(".mySlideDiv");
var currentIndex = 0;
$(".mySlideDiv").each(function(index,item){
if($(this).hasClass("active")) {
currentIndex = index;
}
});
var newIndex = 0;
if(currentIndex <= 0) {
newIndex = allSlide.length-1;
} else {
newIndex = currentIndex-1;
}
$(".mySlideDiv").removeClass("active");
$(".mySlideDiv").eq(newIndex).addClass("active");
$(".mySlideDiv").eq(newIndex).show();
}
function nextSlide() {
$(".mySlideDiv").hide();
var allSlide = $(".mySlideDiv");
var currentIndex = 0;
$(".mySlideDiv").each(function(index,item){
if($(this).hasClass("active")) {
currentIndex = index;
}
});
var newIndex = 0;
if(currentIndex >= allSlide.length-1) {
newIndex = 0;
} else {
newIndex = currentIndex+1;
}
$(".mySlideDiv").removeClass("active");
$(".mySlideDiv").eq(newIndex).addClass("active");
$(".mySlideDiv").eq(newIndex).show();
}
Screenshot on mobile
I want to make a responsive web application, but mobile window isn't filled with the image, and I don't know how to edit the code to make it. I assume that I have to embed the code targeted with mobile web, but I don't know how to do. I attach the image file to explain my situation. Please help.
You can try to put in the css of your container:
width:100%;
height: 100%;
And in the css of your pictures :
width:100%;
height: undefined;
// figure out your image aspect ratio
aspectRatio: 50 / 32;
Add css with media query
#media(max-width:480px) {
img {
width:100% !important;
height: 100% !important;
object-fit: cover; }
}

Automatic and manual slideshow

I have to make a slideshow that has to work both automatic and manual.
For the manual part I have two buttons: next and previous that allows me to see the photos without having to wait a certain period of time between images.
When I don't click on the buttons, the slideshow goes automatic and the images change after six seconds (for example).
My problem is that, after I click on the previous/ next button, the images start to appear faster or they appear more than one on the screen.
Here is the code I am working with:
var slideIndex = 1;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex += n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("hidden");
if (n===undefined){n= ++slideIndex;}
if (n > slides.length) {slideIndex = 1;}
if (n < 1) {slideIndex = slides.length}
$(slides[slideIndex-1]).fadeIn(2000);
slides[slideIndex-1].style.display = "block";
$(slides[slideIndex-1]).delay(3000);
$(slides[slideIndex-1]).fadeOut(1000);
setTimeout(showSlides, 6000);
}
.hidden {
display: none;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<meta charset="utf-8">
<title>jQuery</title>
<link rel="stylesheet" href="lab5.css" media="screen" title="no title">
</head>
<body>
<h1 class="titlu">Goodies</h1>
<div align="center">
<button class="button" onclick="plusSlides(-1)" >Previous</button>
<button class="button" onclick="plusSlides(1)" >Next</button>
</div>
<div class="hidden">
<h4 class="num" > 1 / 5 </h4>
<img src="http://placehold.it/150x150?text=1">
</div>
<div class="hidden">
<h4 class="num"> 2 / 5 </h4>
<img src="http://placehold.it/150x150?text=2">
</div>
<div class="hidden">
<h4 class="num"> 3 / 5 </h4>
<img src="http://placehold.it/150x150?text=3">
</div>
<div class="hidden">
<h4 class="num"> 4 / 5 </h4>
<img src="http://placehold.it/150x150?text=4">
</div>
<div class="hidden">
<h4 class="num"> 5 / 5 </h4>
<img src="http://placehold.it/150x150?text=5">
</div>
</body>
</html>
Is there a way I can make the slideshow return to its "speed" of showing the images every six seconds after I click on previous/next?
Also, how can I prevent it from showing more than one image at a time?
Here's working code for an auto and manual slideshow with the timer as suggested by Scott.
It works with the html and css from this how to which the questioner based his code on.
https://www.w3schools.com/howto/howto_js_slideshow.asp
var slideIndex = 1;
var timer = null;
showSlides(slideIndex);
function plusSlides(n) {
clearTimeout(timer);
showSlides(slideIndex += n);
}
function currentSlide(n) {
clearTimeout(timer);
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("dot");
if (n==undefined){n = ++slideIndex}
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";
timer = setTimeout(showSlides, 5000);
}
What's happening is that you are causing multiple timers to be started, which causes your callback function to run more often than it should.
You need to make sure that you capture the integer that is returned from your timer:
var timer = null; // Do this in a scope that is accessible to all your relevant functions
...then:
timer = setTimeout(showSlides, 6000);
So that you can cancel the timer where appropriate:
clearTimeout(timer);
You will want to clear your timer upon the clicking of the button, which will stop the automatic one from running and then you can start a new one, leaving you with only one running timer.
<!DOCTYPE html>
<html>
<title>W3.CSS</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<style>
.mySlides {display:none;}
</style>
<body>
<h2 class="w3-center">Manual Slideshow</h2>
<div class="w3-content w3-display-container">
<img class="mySlides" src="img_snowtops.jpg" style="width:100%">
<img class="mySlides" src="img_lights.jpg" style="width:100%">
<img class="mySlides" src="img_mountains.jpg" style="width:100%">
<img class="mySlides" src="img_forest.jpg" style="width:100%">
<button class="w3-button w3-black w3-display-left" onclick="plusDivs(-1)">❮</button>
<button class="w3-button w3-black w3-display-right" onclick="plusDivs(1)">❯</button>
</div>
**SCRIPT CODES**
<script>
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";
}
</script>
</body>
</html>
**//CSS CODES**
/* Slideshow container */
.slideshow-container {
height:500px;
position: relative;
margin: auto;
with:800px;
}
/* Hide the images by default */
.mySlides {
display: none;
}
/* Next & previous buttons */
.prev, .next {
background-color:gold;
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 20px;
color: black;
font-weight: bold;
font-size: 24px;
transition: 0.6s ease;
border-radius: 7 7px 7px 7;
}
/* 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);
color:white;
}
/* Caption text */
.text {
color:lime;
font-size: 22px;
padding: 8px 12px;
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
}
/* Number text (1/3 etc) */
.numbertext {
color:lime;
font-size: 22px;
padding: 8px 12px;
position: absolute;
top: 0;
}
/* The dots/bullets/indicators */
.dot {
cursor: pointer;
height: 15px;
width: 15px;
margin: 0 2px;
background-color: #000000;
border-radius: 50%;
display: inline-block;
transition: background-color 0.2s ease;
}
.active, .dot:hover {
background-color: #ff0101;
}
/* Fading animation */
.fade {
-webkit-animation-name: fade;
-webkit-animation-duration: 0.2s;
animation-name: fade;
animation-duration: 6.5s;
}
#-webkit-keyframes fade {
from {opacity: .4}
to {opacity: 1}
}
#keyframes fade {
from {opacity: .4}
to {opacity: 1}

Switching Between Two Slideshows with Javascript

I have a web page with a slideshow. The slideshow has three pictures. I would like to have a button on the page which enables users to switch between this slideshow and another with five different pictures. How would I program this button with JavaScript and where would I add the second slideshow in the HTML?
Current HTML:
<div class="slideshow-container">
<div class="mySlides fade">
<div class="numbertext">1 / 3</div>
<img src="img1.jpg" style="width:100%">
<div class="text">Caption Text</div>
</div>
<div class="mySlides fade">
<div class="numbertext">2 / 3</div>
<img src="img2.jpg" style="width:100%">
<div class="text">Caption Two</div>
</div>
<div class="mySlides fade">
<div class="numbertext">3 / 3</div>
<img src="img3.jpg" style="width:100%">
<div class="text">Caption Three</div>
</div>
<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>
<button>Switch Slideshow</button>
Current CSS:
/* Slideshow container */
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
}
/* Next & previous buttons */
.prev, .next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 16px;
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}
}
Current JavaScript:
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";
}
Many thanks in advance!
Well, you need to first be able to create your slideshow dynamically. Only then will you be able to swap in-and-out different slides. I tried not to refactor your existing code. Also, I did not use jQuery (which I would use personally). Just generate the markup for each slide and set it on the slides div. I had to create an inner div so that the buttons do not get overridden.
var slideshowIndex = 1;
var slideIndex = 1;
var slideshows = [
[
'http://placehold.it/500x300/f00/0ff?text=Foo',
'http://placehold.it/500x300/0f0/f0f?text=Bar',
'http://placehold.it/500x300/00f/ff0?text=Baz'
], [
'http://placehold.it/500x300/f70/07f?text=Fizz',
'http://placehold.it/500x300/0f7/f07?text=Buzz',
'http://placehold.it/500x300/70f/7f0?text=Bang'
]
];
var buttonTextArr = [ 'Show Images', 'Show Pages' ];
function createSlides(slides) {
return slides.map(function(slide, index) {
return [
'<div class="mySlides fade">',
'<div class="numbertext">' + (index + 1) + ' / ' + slides.length + '</div>',
'<img src="' + slide + '">',
'<div class="text">Caption #' + (index + 1) + '</div>',
'</div>'
].join('');
}).join('');
}
function createDots(slides) {
return slides.map(function(slide, index) {
return '<span class="dot" onclick="currentSlide(' + (index + 1) + ')"></span>'
}).join('');
}
function loadSlideshow(slides) {
document.getElementsByClassName('slideshow-slides')[0].innerHTML = createSlides(slides);
document.getElementsByClassName('dots')[0].innerHTML = createDots(slides);
}
function loadNextSlideshow() {
slideshowIndex = (slideshowIndex + 1) % 2;
loadSlideshow(slideshows[slideshowIndex]);
slideIndex = 1; // Reset index
showSlides(slideIndex);
document.getElementsByClassName('switch')[0].innerHTML = buttonTextArr[slideshowIndex];
}
loadNextSlideshow(); // Load the slideshow
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";
}
/* Slideshow container */
.slideshow-container {
max-width: 1000px;
position: relative;
margin: auto;
}
/* Next & previous buttons */
.prev, .next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 16px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
text-shadow: 0.05em 0.05em 0.25em #000;
}
/* 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: 0.4 }
to { opacity: 1 }
}
#keyframes fade {
from { opacity: 0.4 }
to { opacity: 1 }
}
<div class="slideshow-container">
<div class="slideshow-slides"></div>
<a class="prev" onClick="plusSlides(-1)">❮</a>
<a class="next" onClick="plusSlides(1)">❯</a>
</div>
<br />
<div class="dots" style="text-align:center"></div>
<button class="switch" onClick="loadNextSlideshow()">Switch Slideshow</button>
Created plunker here. Please refer below link.
https://plnkr.co/edit/xso6MfwOxQJ4PlDpW90y?p=preview
HTML
<div class="slideshow-container">
<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>
<button>Switch Slideshow</button>
JavaScript:
var slideShowIndex = 1;
var slideShows= [
[
{
'image': 'img1.jpg',
'caption': 'Caption Text'
},
{
'image': 'img1.jpg',
'caption': 'Caption Text'
},
{
'image': 'img1.jpg',
'caption': 'Caption Text'
}
],
[
{
'image': 'img1.jpg',
'caption': 'Caption Text'
},
{
'image': 'img1.jpg',
'caption': 'Caption Text'
},
{
'image': 'img1.jpg',
'caption': 'Caption Text'
},
{
'image': 'img1.jpg',
'caption': 'Caption Text'
},
{
'image': 'img1.jpg',
'caption': 'Caption Text'
}
]
]
buildSlideShow();
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";
}
function buildSlideShow(){
var slideText = '';
var slides = document.getElementsByClassName("slideshow-container");
var slidesToRender = slideShows[slideShowIndex-1];
slidesToRender.forEach(function(value,index){
slideText += '<div class="mySlides fade"><div class="numbertext">'+ index+1+ '/'+slidesToRender.length + '</div><img src="'+value.image+'" style="width:100%"><div class="text">'+value.caption+'</div></div>';
});
slides[0].innerHtml = slideText;
}
hope this works for you.

How to add transition effects to jQuery image slider?

I have made a simple image slider based on this tutorial here. Looks like this:
var currentIndex = 0,
items = $('.container div'),
itemAmt = items.length;
function cycleItems() {
var item = $('.container div').eq(currentIndex);
items.hide();
item.css('display', 'inline-block');
}
var autoSlide = setInterval(function() {
currentIndex += 0;
if (currentIndex > itemAmt - 1) {
currentIndex = 0;
}
cycleItems();
}, 3000);
$('.next').click(function() {
clearInterval(autoSlide);
currentIndex += 1;
if (currentIndex > itemAmt - 1) {
currentIndex = 0;
}
cycleItems();
slide();
});
$('.prev').click(function() {
clearInterval(autoSlide);
currentIndex -= 1;
if (currentIndex < 0) {
currentIndex = itemAmt - 1;
}
cycleItems();
slide();
});
.container {
width: 100%;
height: 100%;
}
.container div {
display: inline-block;
display: none;
}
.container img {
width: 100%;
height: 100%;
object-fit: cover;
}
.galer-btn {
position: absolute;
z-index: 2;
top: 50%;
}
.next {
right: 40px;
padding: 20% 2% 20% 40%;
margin: -20% -1%;
}
.prev {
left: 40px;
padding: 20% 40% 20% 2%;
margin: -20% -2%;
}
.fa {
font-size: 4vw;
color: #ffd2cf;
}
.fa:hover {
cursor: pointer;
-webkit-animation: bounceright .3s alternate ease infinite;
animation: bounceright .3s alternate ease infinite;
}
<html>
<head>
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css">
</head>
<body>
<section class="about">
<i class="fa fa-chevron-right galer-btn next"></i>
<i class="fa fa-chevron-left galer-btn prev"></i>
<div class="container">
<div style="display: inline-block;">
<img src="https://placeimg.com/1000/600/tech" />
</div>
<div>
<img src="https://placeimg.com/1000/600/tech" />
</div>
<div>
<img src="https://placeimg.com/1000/600/tech" />
</div>
<div>
<img src="https://placeimg.com/1000/600/tech" />
</div>
</div>
</section>
</body>
</html>
The result gives me full-screen image slider, which in tutorial is intended to auto slide, but I have managed to disable that by changing currentIndex += 1; to currentIndex += 0; in javascript code. Btw, any recommendations on how to remove the auto slide properly are welcomed.
However, the main question is how do I add some transition effects between images like fade-out etc.?
Also, for left and right buttons I have simply used FontAwesome icons, and it kinda works, but something tells me that might not be the best approach.. Should I use <button> or smthn instead?
So far I have only been learning HTML and CSS, and javascript (or jQuery) is a complete mystery to me right now, so I appreciate any help.

Categories