Resetting a setTimeout using addEventListener Javascript - javascript

i am trying to make a function that when clicking your mouse, can see that you are active or AFK. When the time runs out, this person must be offline. If the person clicks again after the time runs out, the person must come back online. Furthermore, the time must always be reset if he clicks again within the time so you can see that he is active on the page. Does anyone know what I need to adjust here to make it work?
var time;
window.addEventListener('click', function() {
time = setTimeout(function() {
SaveUrl('Save/SetIsOnlineUser', { isOnline: false });
}, 20000);
})
window.addEventListener("click", myFunction);
function myFunction() {
clearTimeout(time)
SaveUrl('Save/SetIsOnlineUser', { isOnline: true });
}

Your logic is flawed as you run opposing logic under two handlers which run under the same event.
To fix this you instead need to use a single event handler. You can set the user online immediately within the click handler, then set the timeout for N seconds later to mark them as offline, something like this:
var time;
window.addEventListener('click', function() {
clearTimeout(time)
SaveUrl('Save/SetIsOnlineUser', {
isOnline: true
});
time = setTimeout(function() {
SaveUrl('Save/SetIsOnlineUser', {
isOnline: false
});
}, 5000);
})
function SaveUrl(u, o) {
console.log('Online:', o.isOnline);
}
Note that I made the timer only 5 seconds to make the effect more obvious.

Related

Turbolinks: How to stop running functions when you leave the page?

In my Rails 5.2.2 app I am using Turbolinks.
I have discovered that when I leave a page, the functions that were started continues.
I have organised my functions below a return statement that checks the body class. In my example below, if the body class is not foobar the functions below do not run.
// assets/javascripts/pages/foobar.js
var goLoop;
$(document).on("turbolinks:load", function() {
if (!$("body").hasClass("foobar")) {
return;
}
return goLoop();
});
goLoop = function() {
return setTimeout((function() {
console.log("Hello");
return goLoop();
}), 1000);
};
First time I visit the page, the goLoop function is triggered.
When I follow a link away from the page, the function runs. If I had not used Turbolinks, this would not have happened.
If I follow another link back to the page, the function is triggered again, so now it runs twice.
How can I avoid this, without disabling Turbolinks?
Use the turbolinks:before-cache to teardown your timeout using clearTimeout. You will need to keep a reference of the current timeout ID. So your solution might look like:
var goLoop;
var timeout;
$(document).on("turbolinks:load", function() {
if (!$("body").hasClass("foobar")) {
return;
}
return goLoop();
});
goLoop = function() {
return timeout = setTimeout((function() {
console.log("Hello");
return goLoop();
}), 1000);
};
$(document).on("turbolinks:before-render", function() {
clearTimeout(timeout);
});
You can use PageVisibilityAPI to see is current page active or not.
and for the loop issue, you should check whether it's exist or not then run timeout function.

Boolean statement not evaluating in javascript

I'm writing a script, and there are two boolean statements that are very similar but giving different results, and I don't see why they conflict with one another.
My function looks like this:
SCRIPT:
(function() {
window.onload = function() {
let stopped = true;
let button = document.getElementById("start-stop");
if (stopped) {
setInterval(function() {
console.log("The timer is working.");
}, 1000);
}
button.addEventListener('click', function(){
if (stopped) {
stopped = false;
console.log(stopped);
} else {
stopped = true;
console.log(stopped);
}
});
}
}
}).call(this);
The basic idea is that when I push the button the setInterval function stops, however it keeps on going even when the if/else function switches stopped to false.
For example, my console.log looks like this:
I.e. stopped = false, but setInterval doesn't terminate.
Why is this not evaluating correctly?
The problem with your code is that you are trying to work on a piece of code that has already started to operate. In simpler words, the setInterval method will be called every 1000ms, no matter what the value of stopped variable is. If you wish to really stop the log, you can do any of these:
clearInterval()
to completely remove the interval or
setInterval(function() {
if (stopped) {
console.log("The timer is working.");
}
}, 1000);
to check if the value of stopped variable has changed or not (after the click) and act accordingly. Choose either of these for your purpose..
you are calling setinterval even before button is clicked .As the event is already triggered you cannot stop just by setting the variable to false ,you need to clear the interval using clearinterval
check the following snippet
var intervalId;
window.onload = function() {
let stopped = true;
let button = document.getElementById("start-stop");
var Interval_id;
button.addEventListener('click', function() {
if (stopped) {
Interval_id = callTimeout();
stopped = false;
} else {
clearInterval(Interval_id);
stopped = true;
}
});
}
function callTimeout() {
intervalId = setInterval(function() {
console.log("The timer is working.");
}, 1000);
return intervalId;
}
<input type="button" id="start-stop" value="click it">
Hope it helps
Put the if(stopped) statement inside the setInterval function because if you used this function once it will keep going..
Another way to stop setInterval function is by using clearInterval, like this
var intervalId = setInterval(function() { /* code here */}, 1000)
// And whenever you want to stop it
clearInterval(intervalId);
When you click the button stopped variable becomes false but the setInterval will not stop because the setInterval code is already executed.. it will not execute again on button click. And if you reload the page what will happen is that stopped variable will be again set to true as you have written at first line and setInterval will execute again ..
Now What you can do is store setInterval in a variable like this
var timer = setInterval(function,1000);
and then when you click the button use this method to clear interval
clearInterval(timer);
this should do the trick .. Hope it helps ..

How to start javascript setinterval once cleared?

I have a setinterval that runes every 5 seconds. this works fine on page load.
I have the following scenarios:
Load page with interval (WORKS)
press button and load new content and stopp interval(WORKS)
Once the new content is no longer desiered, dissmiss it, return to first content and start interval again(DOES NOT WORK)
I have saftys suchs as events for window.blur that also stops the interval so that the browser does not commponsate for all the missing intervals if i would change tabs or something. Keep in mind that step 3 did not work BUT if i would after step 3 change a tab and then return to my original page(execute blur) the interval would start working again.
NOTE all content loading here exept page load is done with ajax calls.
My code:
initializing:
$.automation.worker.bindIntervalEvent("#TanksContent", "/Tank/GetTanks", function() {
$.automation.tanks.tableInit();
});
binding function:
bindIntervalEvent: function (target, url, callback) {
$(window)
.on("focus.mine",
function() {
$.automation.worker.setUpdateInterval(target, url, callback);
})
.on("blur",
function() {
$.automation.worker.stopUpdateInterval();
}).trigger("focus.mine");
}
interval function:
setUpdateInterval: function (target, url, callback) {
if ($.automation.globals.globalInterval.value.length === 0) {
$.automation.globals.globalInterval.value.push(window.setInterval(
function () {
var options = {
loadTarget: target
}
$.automation.worker.getView(url,
function() {
if (callback)
callback();
},
options);
},
5000));
}
}
the function that stops the interval:
stopUpdateInterval: function () {
if ($.automation.globals.globalInterval.value.length === 0)
return;
console.log("deleting");
for (var i = 0; i <= $.automation.globals.globalInterval.value.length; i++) {
window.clearInterval($.automation.globals.globalInterval.value[i])
$.automation.globals.globalInterval.value.splice(i, 1);
console.log($.automation.globals.globalInterval.value.length);
}
}
when stopping the interval i also remove the window bindings:
unBindIntervalEvent: function() {
$(window).off("focus.mine");
$(window).unbind("blur");
}
Back to step 3:
My sucess method in the callback to my getviewfunction is identical to what i execute in the beginning
code:
$(".updatelatest")
.on("click",
function () {
var _this = $(this);
var options = {
loadTarget:"#TanksContent"
}
$.automation.worker.getView("/Tank/GetTanks",
function (data) {
$(_this).switchClass("col-md-5", "col-md-1", 1000, function() {
$(_this).addClass("hidden");
$(".search").switchClass("col-md-5", "col-md-12", 1000, "easeInOutQuad");
})
$.automation.tanks.tableInit();
$.automation.worker.bindIntervalEvent("#TanksContent", "/Tank/GetTanks", function () {
$.automation.tanks.tableInit();
});
$(window).trigger("blur");
}, options);
});
but this does not start the interval. it is clearly initialized since it works when window.blur is executed for example when I change tab but for some reason this is not working beyond that.
i tried triggering the windows blur event and nothing happened, i tried triggering my custom window event "focuse.mine" but nothing happens.
I did not notice this while developing since I had firebug open and every time i checked scripts or css or the console the blur function was executed so I assumed that my code worked as intended but now that it is deployed I notice this.
My head is pounding beyond reason and I can't for figure out where I have gone wrong.
Well this was a fun one. I simply found that when calling the setUpdateInterval(); function directly it gave me the desiered result.
I realized that the reason I had them split like I did was becaouse of the blur event. "Focus.mine" is triggered to start the inteval again ocne a user comes back to the page.

update a page only when there are no mouse events

I would like to update the page only when there are no mouse events,
Such as:
function TimedRefresh(t) {
$('#colorbox').mousemove(event) {
if (mousemove != 0) { //(mousemove == false)
setTimeout("location.reload(false);", t);
}
}
}
It of course does not work. It's called by:
<body onload="JavaScript:TimedRefresh(5000);">
You'd do that like this
$('#colorbox').mousemove(function( event ) {
clearTimeout( $(this).data('timer') );
$(this).data('timer', setTimeout(function() {
window.location.reload();
}, 5000));
});
When the mouse moves within the #colorbox element, the timer is reset, and if no mouse movement is detected, it reloads the page in 5 seconds.
FIDDLE
You need to reverse the logic. Set the timer onload of the page and then clear/restart it when the mouse is moved. If the mouse is not moved for longer than 5 seconds, then the page will refresh:
$(document).ready(function() {
var timer;
resetTimer();
$('#colorbox').mousemove(function() {
resetTimer(timer);
});
function resetTimer() {
clearTimeout(timer);
timer = setTimeout(function() {
window.location.reload(false);
}, 5000);
}
});
Working example
I think you should do something likes this:
Create a hidden field with a default value (maybe 0).
When some MouseEvent is triggered then yo should change the value of the hidden field (maybe 1)
Then, for other side I think you could use a function like setTimeout for comparing and refresing your page. Here you can read more about this function

checking for active timer (setTimeout)

I have a function that contain setTimeout() Method.
I have a button that calls that function, so you could hit this button multiple times and call this function as many times as you want.
Is there a way to actually execute this function, only if there is no other instance of this function that has an active timer?
You would have to keep track of whether you had previously set this timer or not and whether it was still active by using some sort of variable that had a scope that persisted across multiple button presses.
There is no built-in function that will tell you whether the timer you started with this button is still running. You have to create your own. It could work something like this:
var buttonTimer;
function myButtonClick() {
if (!buttonTimer) {
buttonTimer = setTimeout(function() {
buttonTimer = null;
// put your timer code here
}, 2000);
}
}
This will ignore the button click as long as there is a currently active timer. When there is no timer running, it will set a new timer.
Because you're keeping track of the actual timer ID, you have the freedom to implement other behaviors too such as cancelling the previous timer (such as a stop button) or reset the timer to a new time interval by cancelling the previous timer and then setting a new one.
Try this:
var Timer = function() {
var self = this;
this.running = false;
this.run = function() {
if(!self.running) {
self.running = true;
console.log('starting run');
setTimeout(function() {
self.running = false;
console.log('done running!');
}, 5000);
} else {
console.log('i was running already!');
}
}
return this;
}
var aTimer = new Timer();
And add a button for testing purposes:
<button onclick="aTimer.run()">Run!</button>
Fiddle: http://jsfiddle.net/kukiwon/FCuNh/

Categories