setinterval working very randomly - javascript

Hi,
I have this code:
//<![CDATA[
$(window).load(function(){
setInterval(function(){
// toggle the class every 10 seconds
$('body').addClass('new');
setTimeout(function(){
// toggle back after 10 seconds
$('body').removeClass('new');
},10000)
},10000);
});//]]>
This code is supposed to add the class "new" to body 10 seconds later after the page first loads and then remove it after 10 seconds again to start all over going into an endless loop. But it wont work as expected. Sometimes it takes way longer than 10 seconds to add the class and it removes it too soon. Some other times it does it only once and then the loop ends just like that.
Whats wrong here? A more effective and reliable alternative will be also welcome.
Thank you.

You've told the code adding the class to run every 10 seconds. Every 10 seconds, you also schedule a timer to remove the class 10 seconds later. So as of the 20th second, you have a race — will the first timer get there first, or will the second? In any case, it won't have the result you want.
Use a single timer that toggles:
setInterval(function() {
$("body").toggleClass("new");
}, 10000);
As for it taking a long time to start, remember that the window load event doesn't occur until all resources have finished downloading, including all of your images and such. So the whole process may be starting quite a bit later than you expect.
Also note that browsers are increasingly "dialing back" timers in inactive tabs, so your timer may not be running, or may run infrequently, when the window it's in doesn't have focus.
From your comment:
But just as a bonus. What if I want to have the class to last 20 seconds but keep the interval in 10 seconds?
That complicates things. You could have a flag that you toggle, and only toggle the class when the flag is in one state or the other. E.g., something like:
(function() { // Scoping function so the flag isn't a global
var flag = true;
setInterval(function() {
if (flag) {
$("body").toggleClass("new");
}
flag = !flag;
}, 10000);
})();
That will add the class at 10 seconds, toggle the flag at 20, remove the class at 30, toggle the class at 40, then start the cycle again. Adjust as needed.

Related

I need help creating a loop in dev console in firefox

I am trying to use the dev console to give mario a mushroom every 5 seconds (in the browser game super mario html5)
I can give mario mushrooms manually by typing marioShroons(mario) but I would like to have it on loop so I don't have to pause the game every time I want a mushroom. I have tried a while loop and set timeout but I can't figure it out. The only coding languages I familiar with are c++ and html.
**
while(data.time.amount > 0) {
killOtherCharacters()
}
setTimeout(function() {
killOtherCharacters()
}, 1000);
I expected these lines of code to not give me a mushroom, but to automatically kill enemies. But on the first try (the while loop) it froze the tab and I had to reload the page.
With the set timeout, it didn't make any obvious results, it killed all near characters once and then stopped.
You tried using setTimeout, and it only worked once. This is to be expected, because:
Window.setTimeout() sets a timer which executes a function or specified piece of code once the timer expires
From MDN
What you need to do is use setInterval:
The setInterval() method...repeatedly calls a function or executes a code snippet, with a fixed time delay between each call.
From MDN
So in your console, you should write this:
setInterval(killOtherCharacters, 1000);
(I removed the anonymous function because it wasn't needed - you only need an anonymous function if you're passing parameters or doing multiple things. You do need to remove the () for this though).
And if you want to stop the function from executing, assign a variable to the interval:
var killCharacters = setInterval(killOtherCharacters, 1000);
Then call clearInterval upon this variable to clear the interval (stop the loop):
clearInterval(killCharacters);
The reason your while loop froze the page is because Javascript can only do one thing at a time and you told it to always run your while function, blocking all other Javascript from running on your site.
setTimeout is only run once after a set time (see documentation), if you want to run something every x miliseconds it's better to use setInterval instead.
var intervalID = window.setInterval(killOtherCharacters(), 500); //run this every 500 ms
Use setInterval if you want killOtherCharacters() to be called repeatedly.
const interval = setInterval(function() {killOtherCharacters() },1000);
Then when you want the function to stop being called:
clearInterval(interval);

How to cancel out a setTimeout function?

I am making a boon system where the player gets a random boon/buff for 30 seconds and then it removes itself. I have the initial boon in place where it lasts 30 seconds, then removes itself. I push the boon name "Healing Boon" to a empty player.boons = [] array.
However I am running into difficulty the other way around. Lets say the enemy wants to "debuff" my character, and REMOVE the boon instantly. Well because the countdown for my boon lasts 30 seconds, it continues to work until the 30 seconds is up, even if I give the appearance of removal. (I still keep gaining health up to 30 seconds).
I am attributing this to the setTimeout function. If I input 30 seconds, even if later down the line (say 5-10 seconds later), make setTimeout = 0; it will still continue on for the next 30 seconds. It is only on the initial 2nd attempt is setTimeout set to 0. But this is not what I want. I want a system that stops the boon entirely in its tracts and removes any current health buffs it gives the player.
function applyBoonHealing(){
var blessedWind = setInterval(function(){
player.cc.hp += 1;
dom.setText("healthcounter", player.cc.hp);
}, 1000);
player.boons.push("Healing Boon");
postPlayerStatusEffectImage("images/lowerstrengthicon.jpg", "buff", "0", "2", "no");
dom.setText("healthcounter", player.cc.hp);
setTimeout(clearBoon, 30000);
function clearBoon(){
clearInterval(blessedWind);
if (player.boons.includes("Healing Boon", 0)){
var arrayIndex = player.boons.indexOf("Healing Boon", 0);
player.boons.splice(arrayIndex, 1);
}
dom.setText("healthcounter", player.cc.hp);
postPlayerStatusEffectImage("images/lowerstrengthicon.jpg", "buff", "0", "2", "yes");
}
}
clearTimeout() method is solution to this problem:
var boonHandle = setTimeout(clearBoon, 30000);
(...)
clearTimeout(boonHandle); //To cancel your timer
you can use clearTimeout() method,
var mySetTimeoutFunc = setTimeout(clearBoon, 30000);
to stop this you will just have to clearTimeout(mySetTimeoutFunc);
for more info see this http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_win_settimeout_cleartimeout2
clearTimeout is a event to stop Timeout, see below
function myStopFunction() {
clearTimeout(myVar);
}

setInterval function using jquery is causing a "blink"

Personal project using jQuery.
I'm trying to create a function that runs on the hour for 5 seconds. I've done this by getting the current minutes and acting when they are at '00'. (Although for testing the minutes need to be manually changed to the next minute, unless you want to wait an hour to see it run again.)
The function acts on 2 objects, one to add/remove a class, the other to slideUp/Down.
It works, but after the initial running, the slideDown/Up jQuery causes a "blink" every 5 seconds for the rest of the current minute.
I've tried setting the setInterval for 5000, however that hasn't solved the issue. I'm at my wits end really.
While I am also using moment.js elsewhere. This function isn't using moment(). Primarily because I haven't been able to get functions working with moment() either.
Just head to the ....
jsFiddle example
Remember to set the =='00' to the next minute -- sure makes testing easier I really appreciate anyone waiting for this to run. I know it can be a pain to have to wait a minute to see the function at work.
If you watch the function run for 5 seconds, it will stop... but continue watching.. the slideDown() will repeat every 5 seconds until the minute is no longer XX.
How can I stop this repeat??
Thanks!
There're two place for fix.
1. miss usage for 'clearInterval'
clearInterval parameter is The ID of the timer returned by the setInterval() method.
reference this link, w3c definition for clearInterval.
var intervalId = setInterval(function() { alarm(); }, 5000);
...
clearInterval(intervalId );
2. secs >= "05" condition is wrong
change string "05" to int 5.
Believe it or not I sorted it a few moments after posting this.
My conditional was off, and I thought I tried everything. Guess not.
This works
if((mins == "29") && (secs <= '05')) {
$('#focus').slideDown(500);
$('.projcnt').addClass('jump');
} else {
$('#focus').slideUp(300);
$('.projcnt').removeClass('jump');
}
And the ...
working, updated fiddle

What is wrong with the JavaScript code?

I am making a little time killer project for myself, as a way to wait for a forum post.
var factsArray = ['MIT has created a 3D version of Scratch, called StarLogo', 'Duck echos DO quack', 'Ostriches never stick their head in the sand', 'The cigarrete lighter was invented before the match']
var i = 0;
function start() {
while (i < 20) {
setTimeout(function(){document.getElementById('content').innerHTML = factsArray[Math.floor(Math.random() * factsArray.length)];}, 3000);
i = i + 1;
}
setTimeout(function(){document.getElementById('content').innerHTML = "Sixty seconds are up! Go and post!";}, 3000);
}
That's my code; so far, it will only show one item from the array and stop there.
What I want it to do is display one fact from my factsArray every 3 seconds, until 60 seconds has passed, then it will display "Sixty seconds are up! Go and post!".
Why is my code only showing one fact, not one every 3 seconds?
setTimeout is quasi-asynchronous, this code adds 20 timeouts at nearly the same time so they also end at the same time. You will want to set only one timeout and start the next one in the timeout's callback if the total timeout has not been reached yet. Similarily the last statement should be added if the total timeout has been reached.
You could also work with setInterval and clearInterval to implement this.

javascript timer reset at certain interval

I want to restart my count up timer every 5 seconds from the following example: http://jsfiddle.net/stursby/wYUzq/5/
So far, it starts and stops fine, even resets. I would just like to have it automatically go back to 0 and start counting up again after, say, 5 seconds.
I've tried using setInterval() but got weird timing resets from that.
you could add this check in your display() function
if (ms / 5000 > 1)
{
swreset();
startstop();
}
I would use modulos to update the display accordingly. Replace:
$('#count span').text(ms);
with:
$('#count span').text(ms%5000);
at every occurrence.

Categories