JavaScript setInterval problems - javascript

Hey guys I'm trying to run a loop with a setInterval but I would like each element in the array to use a random interval instead of the entire array doing so... this is the code I am using so far
setInterval(function() {
for ( var j = 0; j < aliens.length; j++ ){
aliens[j].shootIt();
}
}, 1000+Math.floor(Math.random() * 4000)
);
but I'm kind of stuck here... Thanks in advance!!!

Move the for loop to outside the interval, then call a function on each iteration to have a fixed j for each interval instance.
var shootIntervals = []; //this goes in the "global" context of your game
for ( var j = 0; j < aliens.length; j++ ) {
intervals(j);
}
function intervals(j) {
shootIntervals[j] = setInterval(function() {
if (!aliens[j]) return;
aliens[j].shootIt();
}, 1000+Math.floor(Math.random() * 4000));
}
//clearInterval(shootIntervals[j]) when they're destroyed
This will give a static random interval to each item in the array.
Fiddle

Assuming you want to call the function at random intervals, the reason setInterval does not work for you is that the random number is computed before the timer is set up. In particular, when you call setInterval both the function expression and the timer interval are computed (once), then the function is called at the computed interval.
In other words, when evaluating your code the random number evaluation might result in an interval of 2.5 seconds. Then your function will be called at 2.5 second intervals.
You should use setTimeout instead.
var shootAliens = function () {
// code to shoot aliens goes here
// ...
setTimeout(shootAliens, 1000+Math.floor(Math.random() * 4000));
};
Now after shooting all of the aliens, this code will schedule the next alien shooting after some random amount of time between 1 and 5 seconds. After that shooting, a new random delay is computed for the next shooting.

See here: how many javascript setTimeout/ setInterval call can be set simultaneously in one page?
Basically, you need to assign the result of setInterval to a variable. Doing so will allow you to then use clearInterval with that variable
I've used that technique in this example. Doing it this way allows you to change the interval assigned to different elements - we first check to see if we have any saved values. If so, we call clearTimeout on them.
From there, we call setInterval on each target item, saving the result to the array - ready to be cleared next time the user presses the button.
<!DOCTYPE html>
<html>
<head>
<title>Moving a couple of spans with different intervals</title>
<script type="text/javascript">
var myIntervals = [];
function Init()
{
if (myIntervals.length != 0)
{
for (var i=0, n=myIntervals.length; i<n; i++)
{
clearInterval(myIntervals.pop());
}
}
myIntervals.push(setInterval(function(){onMove('sp1');}, (Math.random()*500)>>0 ));
myIntervals.push(setInterval(function(){onMove('sp2');}, (Math.random()*500)>>0 ));
myIntervals.push(setInterval(function(){onMove('sp3');}, (Math.random()*500)>>0 ));
}
function constructStyleString(xPos, yPos)
{
var result = "margin-top: " + yPos + "px;";
result += "margin-left: " + xPos + "px;";
return result;
}
function onMove(tgtId)
{
var xPos, yPos;
xPos = Math.random() * 640;
yPos = Math.random() * 480;
var elem = document.getElementById(tgtId);
elem.setAttribute("style", constructStyleString(xPos, yPos));
}
</script>
<style>
span
{
position: absolute;
}
</style>
</head>
<body onload="Init();">
<button onclick="Init();">(Re)set item intervals</button>
<span id='sp1'>This is the first item</span>
<span id='sp2'>This is the second item</span>
<span id='sp3'>This is the third item</span>
</body>
</html>

Related

how can I use setInterval when I want to use while in my function?

<body onload="count()">
<p id="li1"></p>
<script>
let li1 = document.getElementById("li1");
let x = 0;
function count() {
while(x<=1000){
li1.innerHTML = x++;
}
}
setInterval(count,10)
</script>
</body>
I tried to write for instead of using while but it does not work either.
I will reformat your original post shortly. Please be careful to format your future questions properly!
You're doing a few things unnecessarily in your supplied code.
Firstly, you don't need to call count() in the body onload. The setInterval will run after DOM load and effectively handle this for you.
Secondly, because you're using setInterval to run count() every 10ms, you don't need any form of loop, whether it be for or while. The setInterval handles your looping (sort of).
Take a look at the following:
// Get the element we want to put the counter inside
let li1 = document.getElementById("li1");
// Init a variable to hold our counter
let x = 0;
// Init a varible to hold our setInterval timer, so we can disable it when conditions are met.
let counterInterval;
//Define our count() function
function count() {
if (x < 1000){
// Set the innerHTML (I'd rather innerText) to x + 1 as long as x is less than 1000
li1.innerHTML = x++;
} else {
// If x is equal to or greater than 1000, clear the timer
clearInterval(counterInterval);
}
}
//Start our interval time to run count() every 10ms and assign it to our counterInterval variable
counterInterval = setInterval(count,10)
<p id="li1"></p>

How to add multiples of a number and overwrite previous entry using js timing?

I am trying to create a function that continuously adds the same number to itself. Or simply displays multiples of one number every so many seconds with the setInterval method.
For now, let's just say I want to display multiples of ten.
I know how to get a regular while loop to simply display multiples of ten in a row, but what I want to do here is continually replace the previous text every time the function is called. I am trying to create a game and this is going to be the experience calculator. So it needs to display the total experience earned over the given time.
I was trying something along the lines of this:
window.setInterval(
function writeExp ()
{
var j;
while (rounded > 0)
{
var i = w*10;
var j = j + i;
}
document.getElementByID("exp").innerHTML=j;
}, experience)
This seems logical enough to me, but obviously something is wrong, as it does not work. I have tried googling various things like how to sum numbers in javascript or continuously sum, among others, but it is somewhat difficult to word to get it more centered to my needs. So this is the best way to get my questions answered.
There are lot of undefineds in your code, but general example would be
var interval = 1000,
result = 0,
elem = document.getElementByID("exp");
window.setInterval(function () {
result *= 10;
elem.innerHTML = result;
}, interval);
or without global variables
var interval = 1000,
multiply = function (elem) {
var result = 0;
return function () {
result *= 10;
elem.innerHTML = result;
}
};
window.setInterval(multiply(document.getElementByID("exp")), interval);

setInterval() change image

The goal: When the page is loaded, display the image andy_black.jpg. After two seconds, change the image source, and the thus image in the browser, to a second image called andy_white.jpg. This will change back and forth every 2 seconds.
I checked out this article:
SetInterval function calls
(I searched other as well, with the tags [javascript] [function] and the word "setinterval", but most were using jQuery and my intention here is not to use any jQuery, it's an experiment in JavaScript after all).
which was quite helpful for before I had read it my code was much longer and the function was not called in the setInterval() function.
So here's some code:
Suggestions?
var i = 1;
function change_pic() {
i + 1;
if (i == 5) {
i = 1;
}
//I suspect the computer will read i as 5 for some
//tiny amount of time before reverting back to 1
//which I suspect could cause a further problem, but
//is it the source of the current issue?
if (i == 1 || i == 2) {
document.getElementById('img_to_flip').src = "https://cdns-images.dzcdn.net/images/artist/5d9e44027cc266260d7bd932d98f739d/500x500.jpg";
} else {
document.getElementById('img_to_flip').src = "https://media.s-bol.com/q7R3B8QVrAj2/550x549.jpg";
}
}
var pic_src = setInterval(change_pic, 2000);
<img id="img_to_flip" src="https://media.s-bol.com/q7R3B8QVrAj2/550x549.jpg" height="100" width="100" />
You forget to actually reassign the new value to i.
Either use:
i = i + 1;
or
++i;
Also, why count to five when you only have two states? A common paradigm to have an auto-resetting counter is to use modulo arithmetic:
i = (i + 1) % 2;
which guarantees that i will only ever have values of 0 or 1.
FWIW, here's an alternate way of writing the entire feature that'll work for any number of images - just populate the pics array:
(function() { // function expression closure to contain variables
var i = 0;
var pics = ["https://media.s-bol.com/q7R3B8QVrAj2/550x549.jpg", "https://cdns-images.dzcdn.net/images/artist/5d9e44027cc266260d7bd932d98f739d/500x500.jpg"];
var el = document.getElementById('img_to_flip'); // el doesn't change
function toggle() {
el.src = pics[i]; // set the image
i = (i + 1) % pics.length; // update the counter
}
setInterval(toggle, 2000);
})(); // invoke the function expression
<img id="img_to_flip" src="https://media.s-bol.com/q7R3B8QVrAj2/550x549.jpg" height="100" width="100" />
If you want to avoid the delay in first time setInterval call the function before the setInterval as shown in the top answer:
(function() { // function expression closure to contain variables
var i = 0;
var pics = [ "andy_white.jpg", "andy_black.jpg" ];
var el = document.getElementById('img_to_flip');
function toggle() {
el.src = pics[i]; // set the image
i = (i + 1) % pics.length; // update the counter
}
toggle()
setInterval(toggle, 2000);
})(); // invoke the function expression

Javascript variable is undefined

<html>
<head>
<title>Array of images</title>
<script type="text/javascript">
var myPics = new Array[3];
myPics[0] = "./img/blue.png";
myPics[1] = "./img/red.png";
myPics[2] = "./img/yellow.png";
var counter = 0;
function preImg(){
alert(counter);
if(counter == 0)
counter = 4;
counter --;
alert(counter);
document.getElementById("coloredImg").src = myPics[counter];
}
function nextImg(){
if(counter == 3)
counter = -1;
counter ++;
document.getElementById("coloredImg").src = myPics[counter];
}
</script>
</head>
<body>
<img src="./img/blue.png" id="coloredImg" alt="Image not found"/>
<input type="button" onclick="preImg()" value="Previous"/>
<input type="button" onclick="nextImg()" value="Next"/>
</body>
</html>
The problem I encounter is that my counter variable is undefined inside the function. For example when I call the function preImg it alerts me with undefined (when it should be just 0) and the second alert show NaN when it should be a 3. Why my function doesnt recognize my "var counter" it is global isnt it? Do you think the same happens with the variable mypics. Thanks!
new Array[3];
should be
new Array(3);
But rather, use the square bracket notation to create an array (there's no need to specify the length either):
var myPics = [];
Why use this syntax you may ask? There are many reasons:
[] is a faster and shorter way of creating an array.
The Array constructor can be overridden while a syntactical construct like this cannot.
It's much easier to spot in code, making debugging easier.
It has the ability to take a single element (i.e [5]) and not interpret it as the length of the array, a common problem with the cumbersome Array constructor.
var myPics = new Array[3]; should be var myPics = new Array(3);
JsFiddle: http://jsfiddle.net/cbJAc/
Simple slideshow object using a closure over element, pics and counter:
function Slideshow(element, pics) {
var counter = 0;
this.nextImg = function () {
element.src = pics[counter];
counter = (counter + 1) % pics.length;
}
this.nextImg(); // init
}
usage:
var show = new Slideshow(
document.getElementById("coloredImg"),
["./img/blue.png", "./img/red.png", "./img/yellow.png"]
);
show.nextImg(); // red
show.nextImg(); // yellow
show.nextImg(); // blue
Closures make sure that every variable that's in scope when a function is defined will still be in scope when the function is called (or called again). This standard JavaScript technique elegantly solves your counter issue.
Using a modulus based calculation lets the counter repeat the sequence 0,1,2 (in this example).
Edit: Assume you would want to switch to a new image every three seconds:
setInterval(show.nextImg, 3000);

JavaScript / jQuery or something to change text every some seconds

I need JavaScript or jQuery something to change text every few seconds... without the user doing anything.
Example:
"Welcome" changes to "Salmat datang" changes to "Namaste", etc. after 3 seconds and loops back.
As others have said, setInterval is your friend:
var text = ["Welcome", "Hi", "Sup dude"];
var counter = 0;
var elem = document.getElementById("changeText");
var inst = setInterval(change, 1000);
function change() {
elem.innerHTML = text[counter];
counter++;
if (counter >= text.length) {
counter = 0;
// clearInterval(inst); // uncomment this if you want to stop refreshing after one cycle
}
}
<div id="changeText"></div>
You may take a look at the setInterval method. For example:
window.setInterval(function() {
// this will execute on every 5 seconds
}, 5000);
You can use setInterval to call a function repeatedly. In the function you can change the required text.
The list of texts to change between could be stored in an array, and each time the function is called you can update a variable to contain the current index being used. The value can loop round to 0 when it reaches the end of the array.
See this fiddle for an example.
setInterval(function(){
alert('hello, do you have a beer?');
}, 1000);
where 1000 ms = 1 second.

Categories

Resources