Set timeout Running continously - javascript

Please See the below code runs at the rate of 60 frame per second..If any button is clicked isjump will be set to true and below code start excuting.What i am trying is i need to exit out jump() function after 1 second.I tried setout like below...but still lines inside settime out is running indefinitely..Please help me.
What i am actually trying is exit jump function after 1 second.
function jump() {
if (isjump) {
player.posx +=10;
console.log("jumping"); //this line is stopped after 1 second
setTimeout(function () {
isjump = false;
console.log("stopped"); //but this line is continuing
}, 1000);
}
}
I also tried clearTimeout still no use.
var timeoutHandle = window.setTimeout(function () {
isjump = false;
console.log("stopped");
clearTimeout(timeoutHandle);
}, 500);
Edit : For those who think this jump function is called continously...yea it is called continously...For every frame game character position will be updated.

Ok I found The solution..I solved it by running the settimeout function only once inside a loop.
var once = true;
function jump() {
if (isjump) {
player.posx +=10;
console.log("jumping"); //this line is stopped after 1 second
if(once)
{
setTimeout(function () {
isjump = false;
console.log("stopped"); //but this line is continuing
}, 1000);
}
once = false;
}
}

Related

clearTimeout not working on mouseup event

Why is timeout not being cleared in this setup? How can I make up() stop the delayed actions from running?
var active = false;
var delay;
window.addEventListener("mousedown", down, false);
window.addEventListener("mouseup", up, false);
window.addEventListener("mousemove", move, false);
function down(e) {
active = true;
console.log("down")
window.scrollTo(0,document.body.scrollHeight);
}
function up(e) {
active = false;
clearTimeout(delay); //expecting this to clear delay
console.log("up")
window.scrollTo(0,document.body.scrollHeight);
}
function move(e) {
if (active) {
delay = setTimeout(function() {
console.log("move")
window.scrollTo(0,document.body.scrollHeight);
}, 50);
}
}
Expecting delay to be cleared on mouseup but it still executes.
You keep making timeouts on every movement. It does not replace the last one...
Your code is basically this
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- cancels this one
window.clearTimeout(delay)
So you need to remove it before you create a new one
if (active) {
if (delay) window.clearTimeout(delay)
delay = setTimeout(function() {
console.log("move")
window.scrollTo(0,document.body.scrollHeight);
}, 50);
}
If you need to move to fire more than once, that you want to look into throttling scripts.
So, I've learned from the replies that setTimeout produces a new independent timer every time move() is executed. My understanding was that each new timer overwrites the previous one but as this is not the case I had to think of something else.
I did't really explain what I actually needed to achieve with the delay so let me clarify. I want to create a timeout for an action if that action has not been executed for x amount of time. Using setTimeout on the action it self created the problem that the action would still potentially have multiple queued executions waiting to happen even after mouseup events.
So instead I used setTimeout on a new variable that acts as a lock to the action. The result is the following code:
var active = false;
var actionTimeout = false;
var actionTimeStamp;
var actionLock = false;
window.addEventListener("mousedown", down, false);
window.addEventListener("mouseup", up, false);
window.addEventListener("mousemove", move, false);
function down(e) {
active = true;
console.log("down")
window.scrollTo(0,document.body.scrollHeight);
}
function up(e) {
active = false;
console.log("up")
window.scrollTo(0,document.body.scrollHeight);
}
function move(e) {
if (active) {
if ((Date.now() - actionTimeStamp > 500) && (!actionTimeout)) { // get time elapsed and compare to threshold (500ms)
actionTimeout = true; //this is for the if statement above to prevent multiple timeouts
actionLock = false; // set the lock
setTimeout(function() { // remove lock after 50ms
actionTimeout = false;
actionLock = true;
actionTimeStamp = Date.now(); // timestamp here to make sure we don't lock again to soon. (helps if setTimeout is => than threshold.
}, 50);
}
if (actionLock) { //do our action
console.log("move")
window.scrollTo(0,document.body.scrollHeight);
actionTimeStamp = Date.now(); // timestamp last execution
}
}
}
Thanks to everyone for chipping in with comments and answers. Really appreciated.
Answer:
There are a few things to adjust in your code:
Instead of continuously reassigning delay with a new Timeout Timer, simply use an Interval.
You should only set the Timer if the state is active AND delay does not exist already. this stops multiple Timers from existing
There are a few things to adjust and understand about Timers in JavaScript:
When you set a Timer, the variable that houses the Timer is set to return an Integer. This is the ID of the Timer in the current scope.
When you clear a Timer, the variable isn't reset to undefined - it stays the same Integer/ID. This is because you're not clearing the variable, the scope is stopping the Timer that matches the ID the variable houses.
Because of the above you have to explicitly set the variable housing the Timer to undefined (or some other falsy value) after clearing it for an existence check to work.
var active = false;
var delay;
window.addEventListener("mousedown", down, false);
window.addEventListener("mouseup", up, false);
window.addEventListener("mousemove", move, false);
function down(e) {
active = true;
console.log("down")
window.scrollTo(0,document.body.scrollHeight);
}
function up(e) {
active = false;
clearTimeout(delay); //expecting this to clear delay
delay = undefined;
console.log("up")
window.scrollTo(0,document.body.scrollHeight);
}
function move(e) {
if (active) {
if(!delay) {
delay = setInterval(function() {
console.log("move")
window.scrollTo(0,document.body.scrollHeight);
}, 50);
}
}
else { //fallback in case of Browser Queuing issues
if(delay) {
clearTimeout(delay);
delay = undefined;
}
}
}
Edited
Due to comments with issues I added a fallback in mousemove that will remove the timer if the state is inactive, but delay is still defined. I don't believe that you technically should need this, but in practice Browser Event Queuing and Timers occasionally don't get along as expected.

Javascript: how to set intervals with a variable or run code once?

I have a problem with javascript because I want to run code in a function once until a interval is again over. So I have read about a possibilty to use an boolean to control it but without intervals and it is still calling the updatePosition() function over and over without stopping.
Simplyfied I have code in this structure:
var runPerm = false;
function start() {
setInterval(setPerm, 2000);
setInterval(function() {
new updatePosition()
}, 2000);
}
function setPerm() {
runPerm = true;
}
function updatePosition() {
if (runPerm == true) {
//some code that I want to run once.
runPerm = false;
}
}
Has someone an idea to solve the problem?
(A full code: http://pastebin.com/iSFHjct3 )
Use setTimeout.
var runPerm = false;
function start() {
setInterval(setPerm, 2000);
setTimeout(updatePosition, 2000);
}

Need help stopping slideshow using jQuery

I've run into an issue with jQuery code that I'd like some help on. While the next and previous buttons work correctly, there appears to be an issue correctly stopping a slideshow. This is probably something we're completely overlooking, but I can't see what.
There is no JavaScript errors showing in the console. The interrupt method was being reached - at one point I had console.log calls in there to verify (cleaned up for presentation reasons).
http://jsfiddle.net/eLn83ep0/
Your help is much appreciated.
The below code is the functionality for prev/stop/start/next:
if ($(settings.next).size()) {
$(settings.next).bind('click.scrollface', function (e) {
methods.interrupt.call($this);
methods.next.call($this);
});
}
if ($(settings.pause).size()) {
$(settings.pause).bind('click.scrollface', function (e) {
methods.interrupt.call($this);
});
}
if ($(settings.play).size()) {
$(settings.play).bind('click.scrollface', function (e) {
methods.interrupt.call($this);
methods.start.call($this);
});
}
/*
* Setup up prev bindings
*/
if ($(settings.prev).size()) {
$(settings.prev).bind('click.scrollface', function (e) {
methods.interrupt.call($this);
methods.prev.call($this);
});
}
Here is the method for interrupt:
interrupt: function (time) {
return $(this).each(function () {
var data = $(this).data('scrollface');
console.log(data);
console.log('...');
if (!data) {
return false;
}
var $this = $(this),
period = 0;
/*
* Stop the timer, and wait a period of time before restarting it.
* Period defaults to the timer interval
*/
if (data.timer) {
if (typeof time !== "number") {
period = data.interval;
} else {
period = time;
}
methods.stop.call(this);
setTimeout(function resume_timer () {
clearInterval(data.timer);
data.timer = null;
methods.start.call($this);
}, period);
}
});
},
if ($(settings.pause).size()) {
$(settings.pause).bind('click.scrollface', function (e)
methods.stop.call($this);
});
}
if ($(settings.play).size()) {
$(settings.play).bind('click.scrollface', function (e) {
methods.start.call($this);
});
}
and delete the interrupt call in prev and next
//methods.interrupt.call(this);
because the interrupt method stopping the interval method and after timeout starting again, so most time you pause in this timeout but after this timeout the interrupt method starting the intervall again and dont care if you stoped it manually
see your updated fiddle working here http://jsfiddle.net/7ko4rdda/
Edit:
if you call interrupt with 0 for the buttons prev next click handler then you have the expected behavier that the period for the intervall starts new after next/prev click
if ($(settings.prev).size()) {
$(settings.prev).bind('click.scrollface', function (e) {
methods.interrupt.call($this,0);
methods.prev.call($this);
});
}
if ($(settings.next).size()) {
$(settings.next).bind('click.scrollface', function (e) {
methods.interrupt.call($this,0);
methods.next.call($this);
});
}
http://jsfiddle.net/7ko4rdda/1/

Temporarily disabling javascript function from repeating after mouseleave

I have an image gallery that rotates through the rotator class divs on www.creat3dprinters.com that pauses on mouseenter and then fires again 1 second after mouseleave.
However, if a user moves the mouse in and out of the rotator class div quickly the function calls stack up and the visible changes until the 'stack' is completed.
I want the 1 second delay that has not been completed to be cancelled on the 2nd and subsequent mouseenter so that this does not happen.
I have tried using clearTimeout within the mouseenter function but it does not seem to work.
I know there is also the stop() function but that did not work either.
Any suggestions greatly appreciated.
jQuery(document).ready(function () {
var initList = setInterval('RotateIt()', 4000);
$('.rotator').mouseenter(function () {
clearInterval(initList);
}).mouseleave(function () {
timeout = setTimeout(function () {
RotateIt()
}, 1000);
initList = setInterval('RotateIt()', 4000);
})
});
function RotateIt() {
clearTimeout(timeout);
if ($('#rotator-visible').next('.rotator').length == 0) {
$('.rotator:first').attr('id', 'rotator-visible');
$('.rotator:last').removeAttr("id");
} else {
$('#rotator-visible').removeAttr("id").next('.rotator').attr("id", "rotator-visible");
}
}
If a user moves the mouse in and out of the rotator class div quickly the function calls stack up
Then clearTimeout it - and in exactly that place, not only in the delayed RotateIt. The simplest solution would be to call clearTimeout every time before setTimeout, so that you can be sure there is only one active timeout at once.
jQuery(document).ready(function($) {
var initList = setInterval(rotateIt, 4000),
delay = null;
$('.rotator').mouseenter(function(e) {
clearInterval(initList);
}).mouseleave(function(e) {
clearTimeout(delay);
delay = setTimeout(function () {
rotateIt();
initList = setInterval(rotateIt, 4000);
}, 1000);
})
});
function rotateIt() {
if ($('#rotator-visible').next('.rotator').length == 0) {
$('.rotator:first').attr('id', 'rotator-visible');
$('.rotator:last').removeAttr("id");
} else {
$('#rotator-visible').removeAttr("id").next('.rotator').attr("id", "rotator-visible");
}
}

How to auto refresh HTML only if there has been no activity on a page?

I have a website which I would like to auto refresh ONLY if user is not using it for a specific time (ie.180 sec).Is there a way to auto refresh HTML only if there has been no activity on a page?
Thank you!
Two approaches:
1. Use a once-a-second timer and a "timeout" value.
You probably want to wrap this up in an object:
var activityHandler = (function() {
var timerHandle = 0,
timeout;
flagActivity();
function start() {
stop();
flagActivity();
timerHandle = setInterval(tick, 1000);
}
function stop() {
if (timerHandle != 0) {
clearInterval(timerHandle);
timerHandle = 0;
}
}
function flagActivity() {
timeout = new Date() + 180000;
}
function tick() {
if (new Date() > timeout) {
stop();
location.reload();
}
}
return {
start: start,
stop: stop,
flagActivity: flagActivity
};
})();
Then start it on page load:
activityHandler.start();
And ping it every time you see "activity":
activityHandler.flagActivity();
So for instance, you might do this:
if (document.addEventListener) {
document.addEventListener('mousemove', activityHandler.flagActivity, false);
}
else if (document.attachEvent) {
document.attachEvent('onmousemove', activityHandler.flagActivity);
}
else {
document.onmousemove = activityHandler.flagActivity;
}
2. Use a timer you reset every time there's "activity".
This is less ongoing work (we don't have something happening every second), but more work when you flag that activity has happened.
Set up a timer to do the refresh:
var handle = setTimeout(function() {
location.reload();
}, 180000);
...and then cancel and reschedule any time you see whatever you consider to be "activity":
clearTimeout(handle);
handle = setTimeout(...);
You can wrap this up in a function:
var inactivityTimerReset = (function() {
var handle = 0;
function reset() {
if (handle != 0) {
clearTimeout(handle);
}
handle = setTimeout(tick, 180000);
}
function tick() {
location.reload();
}
return reset;
})();
// Kick start
inactivityTimerReset();
// ...and anywhere you see what you consider to be activity, call it
// again
inactivityTimerReset();
Then, again, ping it on every activity. But this is a lot more work than I'd put in a mousemove handler, hence solution #1 above.
var docTimeOut;
function bodyTimeOut()
{
docTimeOut=setTimeout(function(){location.reload();},18000);
}
function resetTimeOut()
{
clearTimeout(docTimeOut);
bodyTimeOut();
}
document.onload = bodyTimeOut;
document.body.onmouseover= resetTimeOut;
you could declare a variable pageActive or something, set it to false, and whenever user does something set it to true.
Then, set a function to execute periodically as frequently as you want with setinterval() that checks this variable, if it's true set it to false to start again, if is false then refresh page.
You can use onblur and onfocus on body element to see if there is a kind of activity on your page.

Categories

Resources