Prevent onbeforeunload function from pausing Javascript timer - javascript

In my web page, I have a countdown timer using Javascript's setTimeout().
function Tick() {
if (RemainingSeconds <= 0) {
alert("Time is up.");
return;
}
RemainingSeconds -= 1;
ElapsedSeconds += 1;
UpdateTimerDisplay();
window.setTimeout("Tick()", 1000);
}
I also have a function triggered on onbeforeunload to "prevent" the user from leaving the page.
window.onbeforeunload = function () {
if (!isIEAjaxRequest) {
return "You should use the logout button to leave this page!";
}
else {
isIEAjaxRequest = false;
}
};
The problem is that when the "Are you sure you want to leave this page?" window prompts, it pauses the setTimeout() function. Any thoughts on how to prevent this?

You can't. Javascript is strictly single threaded, so any modal popup will suspend everything else.

A possible workaround would maybe be to use var before = new Date() to store the time before your dialog appears and then use that one to calculate the passed time after your dialog disappears to make up for the missed seconds.

No, you can't keep updating the UI in the background while the UI thread is consumed with another task (in this case, presenting that native modal dialog prompt).
See Javascript timeout - specification

Related

using window.open inside setInterval()

I want to create a timer that will reload extensions every 10 minutes.
This works, except the window doesn't open. I tried it with www.google.com as well
any thoughts?
var count = 0
var jsUpdatePageTimer = setInterval(updatePage, 5000)
function updatePage(){
console.log(count)
if (count == 3) {
console.log('count is 3')
clearInterval(jsUpdatePageTimer)
} else {
console.log('updating count')
window.open('http://reload.extensions')
count +=1
}
}
popup blockers like to block calls to window.open — you may remember the terrible days when javascript could open popups willy-nilly
nowadays, for window.open to work, you have to use it within a user-initiated call stack
which means, you can only use window.open as the result of a user-triggered event, like a mouse click
button.onclick = () => {
window.open(/*...*/)
}
so you need to ask yourself: what is the relevant user action that should trigger this popup? you need to have the user's consent

Angular 2 application on mobile browser (sleep detection)

After mobile phone puts the browser to sleep, and stays like that for a longer period of time, after wake up it displays wrong data, which otherwise perfectly updates all the data on the page. Is there a way to detect wake up event and what's the best Angular way to reload page/component in that case?
A simple way to achieve this could be run a timer to detect if the browser is asleep.
Using RxJS timeinterval operator,
http://reactivex.io/documentation/operators/timeinterval.html
Rx.Observable.timer(0, 1000).timeInterval().subscribe(timer => {
if (timer.interval > (1000 + SLEEP_THRESHOLD)) {
console.log ('wake-up from sleep detected');
}
});
Other simple way could be,
var now = new Date().getTime();
setInterval (function () {
if ((new Date().getTime() - now) > SLEEP_THRESHOLD) {
console.log ('wake-up from sleep detected');
}
now = new Date().getTime();
}, 1000);
You can reload your app by simply calling JS function
location.reload()
or if you want a more Angular style approach you can try calling your
route again
this.router.navigate(["myRoute"]);
Regarding sleep on mobile browsers you can check out NoSleep.js maybe it can serve your purpose.

Add event to prevent timeout inside Inappbrowser

I have a timeout function
var idleTimeOut = 60; // 1 minute
ResetIdleSecondsEvent = function () {
// Reset counter for all listed event
$(document).on("click mousemove keypress touchstart touchend touchcancel touchmove", function () {
_idleSecondsCounter = 0;
})
}
function VerifyTimeOutInterval() {
// Run every seconds to call function and check if current counter is more than
// the preset time
window.setInterval(CheckIdleTime, 1000);
}
function CheckIdleTime() {
// Check timer only predefined timeout value is not 0, null or empty
if (idleTimeOut != "") {
// Increase counter for seconds
_idleSecondsCounter++;
// Check if current counter is more than the preset timeout period
if (_idleSecondsCounter >= idleTimeOut) {
// Notify user that he/she has been automatically logged out
navigator.notification.alert("You have been automatically logged out due " +
"to inactivity. Please login again.", function () { }, "Logged Out", 'OK');
// Navigate to login page
self.navigateLogout();
}
}
}
This works great in my application when user do nothing for 1 minutes, timeout message will appear and take user to login screen.
But when user open an external link using Inappbrowser and has activity, the idle seconds did not get reset, the timeout message appear and take user back to login. So how do I add the same code into Inapp browser?
As far as I know, the Inappbrowser only has the event loadstart, loadstop, loaderror and exit. I tried the following code to add event into Inappbrowser but no luck.
var inappBrowserObj = window.open(url, '_blank', 'location=yes');
inappBrowserObj.addEventListener('loadstop', ResetIdleSecondsEvent());
inappBrowserObj.addEventListener('loadstop', VerifyTimeOutInterval());
Please tell me what is the correct way to handle timeout function inside Inappbrowser.
Thanks
Your code seems to be wrong while implementing the event handlers. Your callbacks are incorrectly passed and also you don't need to register handlers for same event twice (though you can but not required). Your code should be:
inappBrowserObj.addEventListener('loadstop', ResetIdleSecondsEvent);
Observe how I have passed the callback, your code will execute that function instead of passing it as a callback.
Make your other function calls within the ResetIdleSecondsEvent function.
I hope this helps.

Pause a timer in javascript

I have created a small generic 4 stage pipeline and it simulates for the clock period provided. However i wanted to pause it and resume it in the middle and am not able to do that. This is my FIDDLE and for the pause i thought of adding a flag.
if flag == 1 //keep simulating
if flag == 0 // pause simulation where it is
if flag == 0 and click resume resume simulation until its end
var flag = 1; //initial value
function pause(){
flag = 0;
}
function resume(){
flag = 1;
}
//i try to check if flag is 0 then alert pause or something but no luck
function startSim(){
document.getElementById('clockDiv').innerHTML = 'Clock Period '+clockPeriod;
if(index == 22){
clearInterval(sim);
}else if(flag == 0){
alert("Simulation Paused");
}else{
clockPeriod++;
fetch();
decode();
execute();
store();
index++;
}
}
I would appreciate tips on how to do this.
The problem is not so much your code, but rather how the default way of loading javascript in jsfiddle is working (nl, onload, so an anonymous function)
Therefor your functions pause / resume are no longer available when you click your buttons.
To change this, you can change the way the javascript is loaded inside your page, for you the easiest is:
At this time your code will partly work (alert is very annoying as it pops up at every interval), and your reset won't work because the var sim was defined locally (as #razzak mentioned in another answer)
You should change the JavaScript settings in Fiddler: set "Load Type" to no-wrap and your code will work.
Although I would suggest using clearTimeout instead of flags.
I think thats not just a fiddle issue, look at this:
function start(){
var sim = setInterval(function(){startSim()},500);
}
....
if(index == 22){
clearInterval(sim);
}else if(flag == 0){
alert("Simulation Paused");
....
you re creating sim inside the local scope of the function and then using it inside an other function... this is actually an error.
use this:
function start(){
return setInterval(function(){startSim()},500);
}
FIDDLE
If a user click pause, you setup the flag and handle it in the startSim callback. If flag == 0 you try to simulate pause, but your index counter becomes 22 at 11 secs. It will be clear very fast, before you click pause.
Here is my go: http://jsfiddle.net/j82j14r6/2/
Instead of setInterval, I am using setTimeout and having a function call itself:
function tick()
{
if(!paused)
{
// Do stuff
document.querySelector('#log').value = ticks;
ticks++;
}
setTimeout(tick, 500);
}
This allows for easy control over tickrate, pausing, ending, etc.
Please note that using setTimeout or setInterval is not exactly the most accurate way to calculate time and / or make loops like this, but in case your project is not too important - this is a ok way to do it.
As to why your buttons are not calling the corresponding functions... that is mostly a jsfiddle problem. I fixed this with addEventListener in the JS section, instead of having onclick on the HTML button itself.
<input type = "button" value = "togglepause" id = "pausebutton"/><br/>
document.querySelector('#pausebutton').addEventListener('click', togglepause);

How to detect form submit timeout and re-submit?

We're using an unreliable endpoint to submit a form, which occasionally times out.
window.onload = function(){
document.forms['form-to-third-party-endpoint'].submit()
}
What's the best way to detect the timeout and try re-submitting the form? Perhaps try it 5 times before giving up.
This is a 3rd-party integration -- the form loads up in an iframe and automatically submits to get the HTML content.
Note: Yes, a better solution would be to fix the timeout. But we need to take out system live and can't wait for the 3rd party.
I think the best way is to make a counter in seconds, and when it achieve to 300 (5 minutes) submit the form again. If user leaves page the counter can be stopped with a onbeforeunload.
Something like this
var counter = 0, interval;
window.onload = function() {
interval = setInterval(addCounter, 1000);
}
function addCounter() {
counter++;
if(counter === 300) {
counter = 0;
document.forms['form-to-third-party-endpoint'].submit()
}
}
window.onbeforeunload = function() {
clearInterval(interval);
}
That's a concept, this code was not tested.

Categories