I have the below images and I'm trying to show them one by one by interval of 3 seconds, but I am not able to get it work. It continues to stay on 0 and does not show the image, help would be nice:
<img src="one.png"></img>
<img src="two.png"></img>
javascript :
window.animate = function(){
var timer = '';
var imgs = document.getElementsByTagName('img');
for (var i = 0; i < imgs.length; i++) {
var timer = setInterval(function(){
alert(i);
imgs[i].style.display = 'block';
}, 3000);
if(i == imgs.length){
clearInterval(timer);
}
}
}
This might be what you're looking for:
window.animate = function(){
var imgs = document.getElementsByTagName('img');
var index = 0;
var timer = setInterval(function() {
// Hide all imgs
for (var i = 0; i < imgs.length; i++)
imgs[i].style.display = 'none';
// Display next img
imgs[index].style.display = 'block';
index++;
// Stop after all displayed.
if (index >= imgs.length)
clearInterval(timer);
}, 3000);
}
Here is one way to do it:
Fiddle: http://jsfiddle.net/aecuappp/
HTML:
<img src="http://placehold.it/350x150"></img>
<img src="http://placehold.it/350x150"></img>
<img src="http://placehold.it/350x150"></img>
<img src="http://placehold.it/350x150"></img>
<img src="http://placehold.it/350x150"></img>
<img src="http://placehold.it/350x150"></img>
JS:
var imgs = document.getElementsByTagName('img');
var interval = 3000;
for (var i = 0; i < imgs.length; i++) {
(function (index, time) {
setTimeout(function() {
imgs[index].style.display = 'block';
}, time);
} (i, interval));
interval = interval + 3000;
}
CSS:
img {
display: none;
}
Basically you can start interval at 0 if you want first image to show up immediately. And each time it adds 3 seconds to the timeout since these are all created roughly at the same time. I wrapped the setTimeout in an IIFE to give interval and index scope for when the timeout needs the values at the time we created the timeout.
Since these are essentially all timing out at the same time, you need to implement a callback pattern to your interval to trigger the next one, or you need to increase the interval per index; i.e. set the timer's interval to 3000*(i+1), which will effectively trigger the next one at the delay plus the previous delay. This does not account for the actual images load however. Additionally, I would consider using setTimeout since you only need to do this once.
var img = $('img.targets');
for (var i=0;i<img.length;i++) {
var duration = 3000;
setTimeout( function() {
// do dom work here
}, duration*(i+1));
}
You can accomplish this by queuing up some timeouts using setTimeout and then making sure you are correctly passing the value of i to the function within. You can do that easily by using forEach instead of a regular loop:
window.animate = function() {
var imgs = document.getElementsByTagName('img');
imgs.forEach(function(img, i) {
setTimeout(function() {
img.style.display = 'block';
}, (i + 1) * 3000);
});
};
Related
I am trying to add this image slideshow into my website, However keeping running into a MAximum call stack size exceeded. The slider runs through the images not in the time interval set and then the error occurs
var i = 0; // Start Point
var images = []; // Images Array
var time = 3000; // Time Between Switch
// Image List
images[0] = "http://lorempixel.com/400/200/animals";
images[1] = "http://lorempixel.com/400/200/sports";
images[2] = "http://lorempixel.com/400/200/food";
images[3] = "http://lorempixel.com/400/200/people";
// Change Image
function changeImg(){
document.slide.src = images[i];
// Check If Index Is Under Max
if(i < images.length - 1){
// Add 1 to Index
i++;
} else {
// Reset Back To O
i = 0;
}
// Run function every x seconds
setTimeout("changeImg()", time);
}
// Run function when page loads
window.onload=changeImg;
I am posting this as an answer to have a minimal, complete and verifiable example (mcve) to make sure that the slider is not the culpritd, the code will not give that error.
Here is current syntax - if that still gives an error then there is certainly something else wrong
let i = 0, img;
const images = ["https://via.placeholder.com/150/0000FF/808080?text=Image1",
"https://via.placeholder.com/150/FF0000/FFFFFF?text=Image2",
"https://via.placeholder.com/150/FFFF00/000000?text=Image3",
"https://via.placeholder.com/150/000000/FFFFFF/?text=Image4"
];
const changeImg = function() {
slide.src = images[i];
i++;
if (i >= images.length) i = 0;
}
window.addEventListener("load", function() {
img = document.getElementById("slide");
changeImg();
setInterval(changeImg, 2000);
})
<img id="slide" />
I have a code, a simple automatic slideshow. I would like to place more than 1 slideshow, but they will overwrite each other. Please help me how can i solve this. Please help me to solve this problem. I would like to use these slideshows on the same page, but when a i try only 1 slideshow works. I would like to use 8 types of this slideshow in the future. And 1 extra, i would like to place a simple animation between the pics when they switch.
html:
<div class="pic-wrapper">
<img name="slide" width="400" height="377" object-fit="cover"/>
</div>
and
<div class="pic-wrapper">
<img name="slide2" width="400" height="377" object-fit="cover"/>
</div>
and my javascripts:
<script>
var i = 0; // Start Point
var images = []; // Images Array
var time = 3000; // Time Between Switch
// Image List
images[0] = "img/kosar/kosar1.jpg";
images[1] = "img/kosar/kosar2.jpg";
images[2] = "img/kosar/kosar3.jpg";
images[3] = "img/kosar/kosar4.jpg";
// Change Image
function changeImg(){
document.slide2.src = images[i];
// Check If Index Is Under Max
if(i < images.length - 1){
// Add 1 to Index
i++;
} else {
// Reset Back To O
i = 0;
}
// Run function every x seconds
setTimeout("changeImg()", time);
}
// Run function when page loads
window.onload=changeImg;
</script>
and
<script>
var i = 0; // Start Point
var images = []; // Images Array
var time = 3000; // Time Between Switch
// Image List
images[0] = "img/roplabda/ropi1.jpg";
images[1] = "img/roplabda/ropi2.jpg";
images[2] = "img/roplabda/ropi3.jpg";
images[3] = "img/roplabda/ropi4.jpg";
// Change Image
function changeImg(){
document.slide.src = images[i];
// Check If Index Is Under Max
if(i < images.length - 1){
// Add 1 to Index
i++;
} else {
// Reset Back To O
i = 0;
}
// Run function every x seconds
setTimeout("changeImg()", time);
}
// Run function when page loads
window.onload=changeImg;
</script>
Why don't you merge your script into something like this ?
var slide1 = 0; // First Slide index
var slide2 = 0; //Second Slide Index
var images = []; // Images Array
var time = 3000; // Time Between Switch
// Image List
imageObjects = { 'firstSlide': [
"img/roplabda/ropi1.jpg",
"img/roplabda/ropi2.jpg",
"img/roplabda/ropi3.jpg",
"img/roplabda/ropi4.jpg",
],
'secondSlide': [
"img/kosar/kosar1.jpg",
"img/kosar/kosar2.jpg",
"img/kosar/kosar3.jpg",
"img/kosar/kosar4.jpg"
]};
// Change Image
function changeImg(){
document.slide.src = imageObjects.firstSlide[slide1];
document.slide2.src = imageObjects.secondSlide[slide2];
// Check If Index Is Under Max
if(slide1 < imageObjects.firstSlide.length - 1){
// Add 1 to Index
slide1++;
} else {
// Reset Back To O
slide1 = 0;
}
if(slide2 < imageObjects.secondSlide.length - 1){
// Add 1 to Index
slide2++;
} else {
// Reset Back To O
slide2 = 0;
}
// Run function every x seconds
setTimeout("changeImg()", time);
}
// Run function when page loads
window.onload=changeImg;
If you really want to keep separate scripts for these slideshow, for whatever reason. Then you should probably keep your variables names of "i" & "images" unique and not repeat them in next script.
function slideShow() {
var pageSplash = document.getElementById('splash');
var image = ["pic1.jpg", "pic2.jpg", "pic3.jpg", "pic4.jpg"];
var i = 0;
while (i <= image.length) {
if (i > image.length) {
i = 0;
}
i += 1;
pageSplash.innerHTML = '<img id ="splashImage" src="file:///C:/JonTFS/JonGrochCoding/Javascript%20Practical%20Test/' + image[i] + '">';
setTimeout('slideShow', 5000);
}
}
I'm unsure why my i variable is not being recognized as the i variable from the rest of the function, so when ever I try to run my while loop it get's an error message saying that it's undefined.
I think you want setInterval instead of setTimeout, and you want you be careful that you increment i after you you update innerHTML.
function slideShow() {
var pageSplash = document.getElementById('splash');
var image = ["pic1.jpg", "pic2.jpg", "pic3.jpg", "pic4.jpg"];
var i = 0;
setInterval(function () {
if (i === image.length) {
i = 0;
}
pageSplash.innerHTML = '<img id ="splashImage" src="file:///C:/JonTFS/JonGrochCoding/Javascript%20Practical%20Test/' + image[i] + '">';
i++;
}, 5000)
}
slideShow();
You don't need a while loop. You don't need to reset i. You don't need to set innerHTML.
Click Run code snippet... to see how this works. More explanation below the code
function slideShow(elem, images, delay, i) {
elem.src = images[i % images.length];
setTimeout(function() {
slideShow(elem, images, delay, i+1);
}, delay);
}
// setup slideshow 1
slideShow(
document.querySelector('#slideshow1 img'), // target element
[ // array of images
'http://lorempixel.com/100/100/animals/1/',
'http://lorempixel.com/100/100/animals/2/',
'http://lorempixel.com/100/100/animals/3/',
'http://lorempixel.com/100/100/animals/4/',
'http://lorempixel.com/100/100/animals/5/',
'http://lorempixel.com/100/100/animals/6/'
],
1000, // 1000 ms delay (1 second)
1 // start on slide index 1
);
// setup slideshow 2
slideShow(
document.querySelector('#slideshow2 img'), // target element
[ // array of images
'http://lorempixel.com/100/100/nature/1/',
'http://lorempixel.com/100/100/nature/2/',
'http://lorempixel.com/100/100/nature/3/',
'http://lorempixel.com/100/100/nature/4/',
'http://lorempixel.com/100/100/nature/5/',
'http://lorempixel.com/100/100/nature/6/'
],
500, // 500 ms delay
1 // start on slide 1
);
#slideshow1, #slideshow2 {
width: 150px;
display: inline-block;
}
<div id="slideshow1">
<h2>Animals</h2>
<p>(1000 ms delay)</p>
<!-- initial image -->
<img src="http://lorempixel.com/100/100/animals/1/">
</div>
<div id="slideshow2">
<h2>Nature</h2>
<p>(500 ms delay)</p>
<!-- initial image -->
<img src="http://lorempixel.com/100/100/sports/1/">
</div>
This is a huge improvement because your slideshow function is reusable. It means you can use the same function for any slideshow you want. You can even run multiple slideshows on the same page, as I have demonstrated here.
As others have pointed out, the while loop is unnecessary and, as I pointed out, the setTimout was incorrectly written. The following simplifies your code significantly:
var i = 0;
function slideShow() {
var pageSplash = document.getElementById('splash');
var imageArray = ["pic1.jpg", "pic2.jpg", "pic3.jpg", "pic4.jpg"];
if(i < imageArray.length) {
pageSplash.innerHTML = '<img title='+ imageArray[i] + ' id ="splashImage" src="file:///C:/JonTFS/JonGrochCoding/Javascript%20Practical%20Test/' + imageArray[i] + '">';
}
i++;
}
setInterval(slideShow, 2000);
See: https://jsfiddle.net/dauvc4j6/8/ for a working version.
setTimeout calls the function again so you're re-initializing i to 0 every time you call it. Since you can use setTimeout to call the function recursively you don't need the while loop. Pull i out of the function altogether and make it a global variable.
//i should be global
var i = 0;
function slideShow() {
var pageSplash = document.getElementById('splash');
var image = ["pic1.jpg", "pic2.jpg", "pic3.jpg", "pic4.jpg"];
if (i >= image.length) {
i = 0;
}
i += 1;
pageSplash.innerHTML = '<img id ="splashImage" src="file:///C:/JonTFS/JonGrochCoding/Javascript%20Practical%20Test/' + image[i] + '">';
//set timeout is going to call slideShow again so if it's in the function it will call recursively, if you wanted to stop after a certain point you could nest setTimeout in an if
setTimeout(slideShow, 5000);
}
//you need to initially call the function
slideShow();
I have been trying to write a script that changes an image src every two seconds based on a list.
So, everything is inside a forloop that loops over that list:
$(document).ready(function() {
var lis = {{dias|safe}}; <----- a long list from django. This part of the code works fine.
for (i=0; i<lis.length; i++){
src_img = lis[i][1];
var timeout = setInterval(function(){
console.log(src_img)
$("#imagen").attr("src", src_img);
}, 2000)
}
});
It doesn't work, the console logs thousands of srcs that correspond to the last item on the list. Thanks a lot for your help.
you don't need to run cycle in this case, you just save "pointer" - curentImage and call next array item through function ever 2 sec
var curentImage = 0;
function getNextImg(){
var url = lis[curentImage];
if(lis[curentImage]){
curentImage++;
} else {
curentImage = 0;
}
return url;
}
var timeout = setInterval(function(){
$("#imagen").attr("src", getNextImg());
}, 2000)
var curentImage = 0;
var length = lis.length;
function NewImage(){
var url = lis[curentImage];
if(curentImage < length){
currentImage++;
}
else{
currentImage = 0;
}
return url;
}
var timeout = setInterval(function(){
$("#imagen").attr("src", getNextImg());
}, 2000)
PS: Better than the previous one, Checks for lis length and starts from first if you reach end.
You need something like this
$(document).ready(function() {
var index = 0;
setInterval(function(){
src_img = lis[index++ % lis.lenght][1]; // avoid arrayOutOfBounds
$("#imagen").attr("src", src_img);
}, 2000)
});
What i want is to fade in my sidebar boxes after each other on page load by adding a class.
I have tried the following:
var a = $(".sidebar-box"), delayTime = 2000;
for(var i = 0; i < a.length; i++) {
setTimeout(function(
var ai = $(a[i]);
ai.addClass("fade in");
console.log(ai);
), delayTime);
console.log(delayTime);
delayTime += 2000;
}
The problem is, by the time the class gets added the first time, i already is 4, so the class only gets added to the last box, when actually it should be added to the first one.
You need to create a separate function so that variable i is copied each time:
var a = $(".sidebar-box"), delayTime = 2000;
var func = function(i)
{
setTimeout(function() {
var ai = $(a[i]);
ai.addClass("fade in");
}, delayTime);
}
for(var i = 0; i < a.length; i++) {
func(i);
delayTime += 2000;
}
Instead of adding a class and animating via CSS, if you are okay with using jQuery's fadeIn() method, you can have it like:
var a = $(".sidebar-box"), delayTime = 2000, i = 0;
function animateSideBar() {
if(i >= a.length) return;
// call fadeIn, and pass this function itself as the completion callback
$(a[i]).fadeIn(delayTime, animateSideBar);
i++;
}
animateSideBar(); // start it