Javascript array is not recognizing called variable - javascript

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();

Related

Executing setTimeout() in loop takes effect only in the first iteration [duplicate]

I'm trying to make a few things scroll down the screen in javascript, however, upon execution, it just says a little and displays everything at once. So it's not clearing with the $("#Menu").html('') function and the setTimeout(function {},500) is just setting a timeout for the entire page instead of the code segment.
var MenuData = [
{'Name':'pictures','x':'30'},
{'Name':'blog','x':'50'},
{'Name':'contact','x':'42'}
]
;
var PositionArray = new Array();
$(document).ready(function () {
for (var count = 0; count < 1000; count++) {
$("#Menu").html('');
if (PositionArray[count] != null) {
PositionArray[count]++;
} else {
PositionArray[count] = 0;
}
setTimeout(function () {
for (var i in MenuData) {
$("#Menu").append('<div style="position:relative; left:' + MenuData[i].x + 'px; top:' + PositionArray[i] + 'px; ">123</div>');
}
}, 500);
}
});
Here's the fiddle: http://jsfiddle.net/LbjUP/
Edit: There was a little bit of error in the code that doesn't apply to the question. Here's the new one: http://jsfiddle.net/LbjUP/1/, I just moved PositionArray[count] to the setTimeout function as PositionArray[i]
As stated in the comments, you are creating 1000 timeouts for 500 ms at the same time - after 500 ms all of them will be executed. What you want is to increase the timeout for every scheduled function:
setTimeout(function() {
// do something
}, count * 500);
However, creating 1000 timeouts at once is not a that good idea. It would be better to use setInterval or call setTimeout "recursively" until a count of 1000 is reached, so that you only have one active timeout at a time.
var count = 0;
function update() {
// do something
if (++count < 1000)
setTimeout(update, 500);
// else everything is done
}
update();
Also, if you intend to create timeouts in a loop, be sure to be familiar with closures and their behavior when accessing counter variables after the loop ran.
Try
function recurse ( cnt ) {
for (var i in MenuData) {
$("#Menu").append('<div style="position:relative; left:' + MenuData[i].x + 'px; top:' + PositionArray[i] + 'px; ">123</div>');
}
if (cnt < 1000){
setTimeout(function () { recurse(cnt + 1); }, 500);
}
}
$("#Menu").html('');
if (PositionArray[count] != null) {
PositionArray[count]++;
} else {
PositionArray[count] = 0;
}
recurse(0);
You can also use setInterval
let i = 0;
const interval = setInterval(() => {
console.log(i);
i++;
if (i >= 10) {
clearInterval(interval);
}
}, 1000);`

Javascript show imgs one by one with interval

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);
});
};

Does alert('some message') can make an impact in a callback function - Javascript

I had written a callback function to capture the snapshot of running video using html5 video control and canvas.
I used a for loop to iterate and call the same callback function take the burst capture. If i add alert('') in the callback , the video in the background rerendering when alert message display, the burst snap shot works fine as taking diff photos(frames/images of the running video). But when I removed the alert('') , the video does not run in the background and the bursted images are the same instead of different.
The code
for (var i = 0; i < burstcount; i++) {
var wcam = Webcam;
wcam.burst_snap(function (dataurl, id) {
var arrayindex = passedName + "_" + id;
imgid = imgid + i;
alert(dataurl);
burstcapturedata[arrayindex] = dataurl;
}, i);
var j = 0;
while (j < 10000000000) {
j++;
}
}
DisplayBurstedImages();
}
Yes, actually. Alert holds next execution of code. If your code works with alert it means that you require delay.
Try setTimeout or put the code in the correct place where everything is getting loaded.
I guess it needs time for binding video. you can use setTimeout function for delay.
var delay =100;
setTimeout(function () {/*your function*/ }, delay);
delay = delay + 300;
Your code needs to look something like this:
var wcam = Webcam;
var cnt = 0;
wcam.burst_snap(function(dataurl, id) {
var arrayindex = passedName + "_" + id; //you do not have an array if this is the key
imgid = imgid + cnt; //no clue what this is for
cnt++;
burstcapturedata[arrayindex] = dataurl;
if (cnt===burstcount) {
DisplayBurstedImages();
}
}, 100); //no clue what that value is supposed to be

Image animation with speed control

We have some problem with our image animation with speed control.
It make use of a timeout to change the image, but we want to change the timeout value with a slider, but for some sort of reason, it doesn't work. Can someone help us out ?
We have a Jfiddle here: http://jsfiddle.net/Kbroeren/fmd4xbew/
Thanks! Kevin
var jArray = ["http://www.parijsalacarte.nl/images/mickey-mouse.jpg", "http://www.startpagina.nl/athene/dochters/cliparts-disney/images/donad%20duck-106.jpg", "http://images2.proud2bme.nl/hsfile_203909.jpg"];
var image_count = 0;
function rollover(image_id, millisecs) {
var image = document.getElementById(image_id);
image.src = jArray[image_count];
image_count++;
if (image_count >= jArray.length) {
image_count = 0;
}
var timeout = setTimeout("rollover('" + image_id + "'," + millisecs + ");", millisecs);
}
rollover("img1", 200);
$(function () {
var value;
var $document = $(document),
$inputRange = $('input[type="range"]');
// Example functionality to demonstrate a value feedback
function valueOutput(element) {
var value = element.value,
output = element.parentNode.getElementsByTagName('output')[0];
output.innerHTML = value;
}
for (var i = $inputRange.length - 1; i >= 0; i--) {
valueOutput($inputRange[i]);
};
$document.on('change', 'input[type="range"]', function (e) {
valueOutput(e.target);
rollover("img1", 200);
});
// end
$inputRange.rangeslider({
polyfill: false
});
});
You keep creating more and more infinite function calls without stopping them.
After you call your function the first time, it keeps calling itself.
then you call it again with different interval (millisecs) and it will also start call itself....
You can try two different approach.
1.Use setInterval instead of setTimeout. Use clearInterval to clear the interval before setting it with a new value.
/// Call animation() every 200 ms
var timer = setInterval("Animation()",200);
function ChageSpeed(miliseces){
///Stop calling Animation()
clearInterval(timer);
/// Start calling Animation() every "miliseces" ms
timer = setInterval("Animation()",miliseces);
}
function Animation(){
/// Animation code goes here
}
2.Or, Instead, Set your interval as a global variable (not cool) and just change it value when the user want to change the animation speed.
var millisecs = 200;
function rollover(image_id) {
var image = document.getElementById(image_id);
image.src = jArray[image_count];
image_count++;
if (image_count >= jArray.length) {
image_count = 0;
}
var timeout = setTimeout("rollover('" + image_id + "'," + millisecs + ");", millisecs);
}
$document.on('change', 'input[type="range"]', function (e) {
valueOutput(e.target);
millisecs = YourNewValue;
});

Change img src every second using Jquery and Javascript

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)
});

Categories

Resources