Why won't my images fade in and out? - javascript

So I am currently working on a slideshow project in jQuery where images will fade in and out. The problem is that this only works on my KhanAcademy project, and not on my CodePen - Pen.
Can someone please tell me the issue on my CodePen? Thank you!
Code:
var slideShow = function(container, time, effect) {
container = document.querySelector(container);
this.images = [];
this.curImage = 0;
if (effect === "fade") {
for (i = 0; i < container.childElementCount; i++) {
this.images.push(container.children[i]);
this.images[i].style.opacity = 0;
}
// Handle going to to the next slide
var nextSlide = function() {
for (var i = 0; i < this.images.length; i++) {
if (i != this.curImage) this.images[i].style.opacity = 0;
}
this.images[this.curImage].style.opacity = 1;
this.curImage++;
if (this.curImage >= this.images.length) {
this.curImage = 0;
}
window.setTimeout(nextSlide.bind(document.getElementById(this)), time);
};
nextSlide.call(this);
} else if (effect === "clickFade") {
for (i = 0; i < container.childElementCount; i++) {
this.images.push(container.children[i]);
this.images[i].style.opacity = 0;
}
// Handle going to to the next slide
var nextSlideClick = function() {
for (var i = 0; i < this.images.length; i++) {
if (i != this.curImage) this.images[i].style.opacity = 0;
}
this.images[this.curImage].style.opacity = 1;
this.curImage++;
if (this.curImage >= this.images.length) {
this.curImage = 0;
}
window.setTimeout(nextSlideClick.bind(document.getElementById(this)), time);
};
nextSlideClick.call(this);
}
};
slideShow(".slideshow", 2000, "fade");
h1 {
font-family: 'Montserrat', sans-serif;
}
.slide {
transition: opacity 0.5 s;
position: absolute;
top: 1;
}
<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet">
<h1>Exatreo.js - Slideshow library</h1>
<div class="slideshow">
<img class="slide" src="https://www.kasandbox.org/programming-images/animals/birds_rainbow-lorakeets.png" alt="Rainbow lorakeets" />
<img class="slide" src="https://www.kasandbox.org/programming-images/animals/butterfly.png" alt="Butterfly" />
<img class="slide" src="https://www.kasandbox.org/programming-images/animals/cat.png" alt="Cat" />
<img class="slide" src="https://www.kasandbox.org/programming-images/animals/crocodiles.png" alt="Crocodiles" />
<img class="slide" src="https://www.kasandbox.org/programming-images/animals/fox.png" alt="Fox" />
</div>

If you will check your css with the validator you will get this error:
0.5 is not a transition value : opacity 0.5 s
And you can see that you have a space between the 0.5 and the s.
Remove this space and it will work as expected.
var slideShow = function(container, time, effect) {
container = document.querySelector(container);
this.images = [];
this.curImage = 0;
if (effect === "fade") {
for (i = 0; i < container.childElementCount; i++) {
this.images.push(container.children[i]);
this.images[i].style.opacity = 0;
}
// Handle going to to the next slide
var nextSlide = function() {
for (var i = 0; i < this.images.length; i++) {
if (i != this.curImage) this.images[i].style.opacity = 0;
}
this.images[this.curImage].style.opacity = 1;
this.curImage++;
if (this.curImage >= this.images.length) {
this.curImage = 0;
}
window.setTimeout(nextSlide.bind(document.getElementById(this)), time);
};
nextSlide.call(this);
} else if (effect === "clickFade") {
for (i = 0; i < container.childElementCount; i++) {
this.images.push(container.children[i]);
this.images[i].style.opacity = 0;
}
// Handle going to to the next slide
var nextSlideClick = function() {
for (var i = 0; i < this.images.length; i++) {
if (i != this.curImage) this.images[i].style.opacity = 0;
}
this.images[this.curImage].style.opacity = 1;
this.curImage++;
if (this.curImage >= this.images.length) {
this.curImage = 0;
}
window.setTimeout(nextSlideClick.bind(document.getElementById(this)), time);
};
nextSlideClick.call(this);
}
};
slideShow(".slideshow", 2000, "fade");
h1 {
font-family: 'Montserrat', sans-serif;
}
.slide {
transition: opacity 0.5s;
position: absolute;
top: 1;
}
<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet">
<h1>Exatreo.js - Slideshow library</h1>
<div class="slideshow">
<img class="slide" src="https://www.kasandbox.org/programming-images/animals/birds_rainbow-lorakeets.png" alt="Rainbow lorakeets" />
<img class="slide" src="https://www.kasandbox.org/programming-images/animals/butterfly.png" alt="Butterfly" />
<img class="slide" src="https://www.kasandbox.org/programming-images/animals/cat.png" alt="Cat" />
<img class="slide" src="https://www.kasandbox.org/programming-images/animals/crocodiles.png" alt="Crocodiles" />
<img class="slide" src="https://www.kasandbox.org/programming-images/animals/fox.png" alt="Fox" />
</div>

Related

Simple JS carousel need advice

I am trying to create a simple carousel with JavaScript, I am having one issue, how can I display the slides, based on the startingPosition value?
const items = document.getElementsByClassName("carousel__item")
let startingPosition = 0;
let totalItems = items.length;
const prevButton = document.querySelector(".prev")
const nextButton = document.querySelector(".next")
prevButton.addEventListener("click", () => {
if(startingPosition == 0) return;
startingPosition--;
}
);
nextButton.addEventListener("click", () => {
startingPosition++;
if(startingPosition == totalItems) {
startingPosition = 0;
}
}
);
.carousel {
max-width: 400px;
margin: 0 auto;
}
.carousel__item > img {
width: 100%;
}
<div class="carousel">
<div class="carousel__item">
<img src="https://www.greenqueen.com.hk/wp-content/uploads/2021/06/WEF-Investments-In-Nature-Based-Solutions-Have-To-Triple-By-2030-To-Address-Climate-Change-Biodiversity-Loss.jpg" />
</div>
<div class="carousel__item">
<img src="https://tr-images.condecdn.net/image/LDM0pgM40l1/crop/2040/f/gettyimages-1146431497.jpg" />
</div>
</div>
<button class="prev">
Prev
</button>
<button class="next">
Next
</button>
You need to write function to show the active image based on startingPosition.
showSlides does the same thing. It goes through all carousel__item and hide all of them and show only the picture in startingPosition position.
const items = document.getElementsByClassName("carousel__item")
let startingPosition = 0;
let totalItems = items.length;
showSlides(startingPosition);
const prevButton = document.querySelector(".prev")
const nextButton = document.querySelector(".next")
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("carousel__item");
if (n > slides.length) { startingPosition = 1 }
if (n < 1) { startingPosition = slides.length }
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slides[startingPosition - 1].style.display = "block";
}
prevButton.addEventListener("click", () => {
if (startingPosition == 0) return;
startingPosition--;
showSlides(startingPosition);
}
);
nextButton.addEventListener("click", () => {
startingPosition++;
if (startingPosition == totalItems) {
startingPosition = 0;
}
showSlides(startingPosition);
});
.carousel {
max-width: 400px;
margin: 0 auto;
}
.carousel__item > img {
width: 250px;
height: 150px;
}
<div class="carousel">
<div class="carousel__item">
<img src="https://www.w3schools.com/howto/img_lights_wide.jpg" />
</div>
<div class="carousel__item">
<img src="https://tr-images.condecdn.net/image/LDM0pgM40l1/crop/2040/f/gettyimages-1146431497.jpg" />
</div>
</div>
<button class="prev">
Prev
</button>
<button class="next">
Next
</button>

Error x[index] is undefined" in slides HTML/CSS/JS

I'm new in front end development and I want some help with this error
can you please help me fix the problem im facing
var index = 1; show(index);
function move(n) { show(index = index + n); }
function show(n) { var i; var x =
document.getElementsByClassName("slides"); for (i = 0; i < x.length;
i++) { x[i].style.display = "none"; } x[index].style.display =
"block"; }
.w3-content{max-width:980px;margin:auto}
.w3-center{text-align:center!important}
.w3-btn-floating:hover{box-shadow:0 8px 16px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19)}
.w3-button{color:#000;background-color:#f1f1f1;padding:8px 16px}.w3-button:hover{color:#000!important;background-color:#ccc!important}
.w3-btn,.w3-btn-floating{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
.w3-btn-floating{display:inline-block;text-align:center;color:#fff;background-color:#000;position:relative;overflow:hidden;z-index:1;padding:0;border-radius:50%;cursor:pointer;font-size:24px}
.w3-btn-floating{width:40px;height:40px;line-height:40px}
.w3-btn-floating:disabled{cursor:not-allowed;opacity:0.3}.w3-disabled *,:disabled *{pointer-events:none}
.w3-btn-floating{-webkit-transition:background-color .25s,color .15s,box-shadow .25s,opacity 0.25s,filter 0.25s,border 0.15s;transition:background-color .25s,color .15s,box-shadow .15s,opacity .25s,filter .25s,border .15s}
<!DOCTYPE html>
<html>
<body>
<div class="w3-content" style="max-width:400px;position:relative">
<img class="slides" src="https://i.stack.imgur.com/Qypol.jpg" style="width:100%">
<img class="slides" src="https://i.stack.imgur.com/yU7fs.jpg" style="width:100%">
<img class="slides" src="https://i.stack.imgur.com/xxLmR.jpg" style="width:100%">
<img class="slides" src="https://i.stack.imgur.com/YiIiQ.jpg" style="width:100%">
<a class="w3-btn-floating" style="position:absolute;top:45%;left:0" onclick="move(-1)">❮</a>
<a class="w3-btn-floating" style="position:absolute;top:45%;right:0" onclick="move(1)">❯</a>
</div>
</body>
</html>
So the problem with your JS code is that you don't consider changing index based on length of the slides which are your clicks to the right and left buttons.
What I mean to say you should think what will happen when you keep clicking the right button so every time the index will increase so you need to set it back to the first image or slide in this case with this condition if (n > x.length) {index = 1}
and vice versa if (n < 1) {index = x.length} for the case when you decrease the images or slides (left button).
Here is the JS code you need to solve this problem:
var index = 1;
show(index);
function move(n) {
show(index = index + n);
}
function show(n) {
var i;
var x = document.getElementsByClassName("slides");
if (n > x.length) {index = 1}
if (n < 1) {index = x.length}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[index-1].style.display = "block";
}
Fiddle(View):
var index = 1;
show(index);
function move(n) {
show(index = index + n);
}
function show(n) {
var i;
var x = document.getElementsByClassName("slides");
if (n > x.length) {index = 1}
if (n < 1) {index = x.length}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[index-1].style.display = "block";
}
.w3-content{max-width:980px;margin:auto}
.w3-center{text-align:center!important}
.w3-btn-floating:hover{box-shadow:0 8px 16px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19)}
.w3-button{color:#000;background-color:#f1f1f1;padding:8px 16px}.w3-button:hover{color:#000!important;background-color:#ccc!important}
.w3-btn,.w3-btn-floating{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
.w3-btn-floating{display:inline-block;text-align:center;color:#fff;background-color:#000;position:relative;overflow:hidden;z-index:1;padding:0;border-radius:50%;cursor:pointer;font-size:24px}
.w3-btn-floating{width:40px;height:40px;line-height:40px}
.w3-btn-floating:disabled{cursor:not-allowed;opacity:0.3}.w3-disabled *,:disabled *{pointer-events:none}
.w3-btn-floating{-webkit-transition:background-color .25s,color .15s,box-shadow .25s,opacity 0.25s,filter 0.25s,border 0.15s;transition:background-color .25s,color .15s,box-shadow .15s,opacity .25s,filter .25s,border .15s}
<!DOCTYPE html>
<html>
<body>
<div class="w3-content" style="max-width:400px;position:relative">
<img class="slides" src="https://i.stack.imgur.com/Qypol.jpg" style="width:100%">
<img class="slides" src="https://i.stack.imgur.com/yU7fs.jpg" style="width:100%">
<img class="slides" src="https://i.stack.imgur.com/xxLmR.jpg" style="width:100%">
<img class="slides" src="https://i.stack.imgur.com/YiIiQ.jpg" style="width:100%">
<a class="w3-btn-floating" style="position:absolute;top:45%;left:0" onclick="move(-1)">❮</a>
<a class="w3-btn-floating" style="position:absolute;top:45%;right:0" onclick="move(1)">❯</a>
</div>
</body>
</html>

Autoplay on slider doesn't play after showing next div

I want to have an autoplay in my slider but I encounter a problem. After showing next div it doesn't continue to show another div.
How can I fix this?
Here is my code:
<div class="container">
<div class="mySlides active" style="background-image: url('images/1.jpg')">
</div>
<div class="mySlides" style="background-image: url('images/2.jpg');">
</div>
<div class="mySlides" style="background-image: url('images/3.jpg');">
</div>
</div>
<script>
var currentSlide = 1;
var isPlaying = true;
function nextSlide() {
showSlide(currentSlide += 1)
}
function showSlide() {
var slides = document.getElementsByClassName("mySlides");
if (currentSlide > slides.length) {
currentSlide = 1;
}
for (i = 1; i < slides.length; i++) {
slides[i].style.opacity = "0";
}
slides[currentSlide-1].style.opacity = "1";
slides[currentSlide-1].style.transition = "all .5s";
// slides[slideIndex-1].setAttribute("style", "opacity: 1; transition: ease .5s;");
}
if (isPlaying) {
setTimeout(nextSlide, 1000);
}
</script>
I have modified your provided code a bit. Here is working example:
HTML
<div class="container">
<div class="mySlides" style="background-image: url('images/1.jpg')">1
</div>
<div class="mySlides" style="background-image: url('images/2.jpg');">2
</div>
<div class="mySlides" style="background-image: url('images/3.jpg');">3
</div>
Javascript:
var currentSlide = 1;
var isPlaying = true;
function nextSlide() {
showSlide(currentSlide += 1)
}
function showSlide() {
var slides = document.getElementsByClassName("mySlides");
if (currentSlide >= slides.length) {
currentSlide = 0;
}
for (i = 0; i < slides.length; i++) {
slides[i].style.opacity = "0";
slides[i].style.display = "none";
}
slides[currentSlide].style.display = "block";
slides[currentSlide].style.opacity = "1";
slides[currentSlide].style.transition = "all .5s";
// slides[slideIndex-1].setAttribute("style", "opacity: 1; transition: ease .5s;");
}
if (isPlaying) {
setInterval(nextSlide, 500);
}

Slideshow not working :/

<html>
<head>
<style>
.mySlides {
display:none;
height:200px;
width:800px;
margin-left:auto;
margin-right:auto;
}
</style>
<head>
<body>
<script>
var myIndex = 0;
carousel();
function carousel() {
var i;
var x = document.getElementsByClassName("mySlides");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
myIndex++;
if (myIndex > x.length) { myIndex = 1 }
x[myIndex - 1].style.display = "block";
setTimeout(carousel, 2000); // Change image every 2 seconds
}
</script>
<section id="images">
<img id="yeah" class="mySlides" src="image1.jpg" />
<img class="mySlides" src="image2.jpg" />
<img class="mySlides" src="image3.jpg" />
</section>
</body>
</html>
So i'm not sure why this automatic slideshow isn't working when it was copied almost verbatim from w3schools, the result doesn't display anything. Ive been trying to find out whats wrong with it for about a day and a half now and still no luck, Please Help!
I believe that this was not working because before the edit, your script tag was before your html tags..hence the script executed the function and raised a couple of errors since your html was not fully loaded...
Place your script tag below your html codes (in this scenario)
see snippet
<html>
<style>
.mySlides {
display: none;
height: 200px;
width: 800px;
margin-left: auto;
margin-right: auto;
}
</style>
<body>
<section id="images">
<img id="yeah" class="mySlides" src="https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcRxjU7k88PhMjr8f7tCmwOhiaik22dtZYY773ZtWG4TSOLgspnOeIhpOHHa" />
<img class="mySlides" src="https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcQiUk8V76AvsGFAkDEHVjnZID8iFgB8LF7mQMbVVDB8mLnxb81v1g" />
</section>
</body>
</html>
<script>
var myIndex = 0;
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(x, myIndex);
if (myIndex > x.length) {
myIndex = 1
}
x[myIndex - 1].style.display = "block";
setTimeout(carousel, 2000); // Change image every 2 seconds
}
</script>
Here is a slightly different implementation of the slideshow that allows auto rotation of the images.
var image_number = 0;
function slideshow(num) {
var images = new Array("image1.jpg", "image2.jpg", "image3.png");
var description = new Array("Title1", "Title2", "Title3");
var image_length = images.length - 1;
image_number = image_number + num;
if (image_number > image_length) {
image_number = 0;
}
if (image_number < 0) {
image_number = image_length;
}
// Change <img> src and image description in DOM
document.getElementById("slideshow").src=images[image_number];
document.getElementById("description").innerHTML = description[image_number];
return false;
}
function auto_slideshow() {
setInterval(function(){
slideshow(1);
}, 3000);
}

Why isn't my event listener working inside the function?

I have a function that makes a slideshow in JavaScript. While trying to add a feature, changing the slide with fade on click, my function stopped working, what is wrong with it? Complete code on Khan Academy
var slideShow = function(container, time, effect) {
container = document.querySelector(container);
this.images = [];
this.curImage = 0;
if (effect === "click_fade") {
for (i = 0; i < container.childElementCount; i++) {
this.images.push(container.children[i]);
this.images[i].style.opacity = 0;
}
// Handle going to to the next slide
var nextSlideClick = function() {
for (var i = 0; i < this.images.length; i++) {
if (i != this.curImage) this.images[i].style.opacity = 0;
}
this.images[this.curImage].style.opacity = 1;
this.curImage++;
if (this.curImage >= this.images.length) this.curImage = 0;
window.setTimeout(nextSlide.bind(document.getElementById(this)), time);
};
container.addEventListener("click", nextSlideClick)
}
nextSlide.call(this);
};
slideShow("#slideshow", 2000, "click_fade");
.slide {
transition: opacity 0.5s;
position: absolute;
top: 0;
}
<div id="slideshow">
<img class="slide" src="https://www.kasandbox.org/programming-images/animals/birds_rainbow-lorakeets.png" alt="Rainbow lorakeets" />
<img class="slide" src="https://www.kasandbox.org/programming-images/animals/butterfly.png" alt="Butterfly" />
<img class="slide" src="https://www.kasandbox.org/programming-images/animals/cat.png" alt="Cat" />
<img class="slide" src="https://www.kasandbox.org/programming-images/animals/crocodiles.png" alt="Crocodiles" />
<img class="slide" src="https://www.kasandbox.org/programming-images/animals/fox.png" alt="Fox" />
</div>
No result, what is wrong?
You can try the following:
<style>
.slide {
transition: opacity 0.5s;
position: absolute;
top: 0;
}
</style>
<div id="slideshow">
<img class="slide" src="https://www.kasandbox.org/programming-images/animals/birds_rainbow-lorakeets.png" alt="Rainbow lorakeets" />
<img class="slide" src="https://www.kasandbox.org/programming-images/animals/butterfly.png" alt="Butterfly" />
<img class="slide" src="https://www.kasandbox.org/programming-images/animals/cat.png" alt="Cat" />
<img class="slide" src="https://www.kasandbox.org/programming-images/animals/crocodiles.png" alt="Crocodiles" />
<img class="slide" src="https://www.kasandbox.org/programming-images/animals/fox.png" alt="Fox" />
</div>
<script>
var slideShow = function(container, time, effect) {
container = document.querySelector(container);
this.images = [];
this.curImage = 0;
if (effect === "click_fade") {
for (i = 0; i < container.childElementCount; i++) {
this.images.push(container.children[i]);
this.images[i].style.opacity = 0;
}
// Handle going to to the next slide
var nextSlideClick = function() {
for (var i = 0; i < this.images.length; i++) {
if (i != this.curImage) this.images[i].style.opacity = 0;
}
this.images[this.curImage].style.opacity = 1;
this.curImage++;
if (this.curImage >= this.images.length) this.curImage = 0;
window.setTimeout(nextSlideClick.bind(document.getElementById(this)), time);
};
container.addEventListener("click", nextSlideClick)
nextSlideClick.call(this);
}
};
slideShow("#slideshow", 2000, "click_fade");
</script>
Made some minor changes in this jsfiddle : Here

Categories