How to detect browser refresh alone - javascript

Hi i want to detect browser refresh alone in javascript. The below code am using is detecting the browser close as well as refresh, back etc.
window.onbeforeunload = function (evt) {
var message = 'Are you sure you want to leave?';
console.log(evt);
console.log(window.event);
console.log(event);
if (typeof evt == 'undefined') {
evt = window.event;
}
if (evt) {
evt.returnValue = message;
}
return evt;
}

You can save the current time to session storage from onbeforeunload, then when the page loads look in session storage for a time and, if you find one and it's within (say) a couple of seconds, assume it's a refresh.
window.onbeforeunload = function() {
sessionStorage.setItem("left", Date.now());
};
and elsewhere, in code that runs when the page loads:
var left = sessionStorage.getItem("left");
if (left && (Date.now() - left) < 2000) {
// Refreshed
}
Full example (live copy):
(function() {
"use strict";
window.onbeforeunload = function() {
sessionStorage.setItem("left", Date.now());
};
var left = sessionStorage.getItem("left");
if (left && (Date.now() - left) < 2000) {
// Refreshed
display("Refreshed");
} else {
// Freshly loaded
}
})();

Related

Content script unloads when page is not visited for a long time

I'm working on a browser extension that needs to be constantly running, even after an automatic refresh in the background. The problem is, that the page randomly automatically unloads and the script just shuts off. I need to find a way to keep the content script on at all times. Here's part of the code:
// content.js:
function run(fn) {
if(typeof(Worker) !== "undefined") {
if(typeof(w) == "undefined") {
w = new Worker(URL.createObjectURL(new Blob(['('+fn+')()'])));
}
w.onmessage = function(event) {
if (isNaN(grabbedmin) && ID) {
bump() // Note: the bump function refreshes in the page.
w.terminate();
}
if ($("[href='/server/bump/" + ID + "']").text().includes("Bump")) {
bump()
w.terminate();
}
document.getElementById("bumpcount").innerHTML = "Autobumper Enabled: " + getCurrentTimestamp();
if (numberwow == grabbedmin) {
bump()
w.terminate();
}
};
}
}
The code above basically gets run every minute by this worker:
// content.js:
const worker = run(function() {
var i = 0;
function timedCount() {
i = i + 1;
postMessage(i);
setTimeout(function(){timedCount()},1000);
}
timedCount();
});
Is there a way for background.js to detect that content.js is not running (or that the page is unloaded) when it should be and then reload it?
Note: You can find the script here: https://github.com/Theblockbuster1/disboard-auto-bump
After looking through the docs and looking at examples, I put this together:
chrome.tabs.query({
url: ["*://disboard.org/*dashboard/servers", "*://disboard.org/*dashboard/servers/"] // finds matching tabs
}, function(tabs) {
tabs.forEach(tab => {
chrome.tabs.update(tab.id,{autoDiscardable:false});
});
});
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
// checks if the browser automatically re-enabled autoDiscarding and disables it
if (changeInfo.autoDiscardable == true) chrome.tabs.update(tabId,{autoDiscardable:false});
});

If Deeplink url not work send user to download page

I need to implement a javascript where I can detect if my deep link is worked or not, If it works then it should remain same but if it does not work then it must start download file.
For that, i use timeout function to do it. Here is sample code I used.
setTimeout(function () { window.location = "https://itunes.apple.com/appdir"; }, 25);
window.location = "appname://";
But this code works fine on android and ios but it is creating problem while it comes to the desktop browser. In desktop browser after Deeplink works properly, timeout function do not stops and it redirects to download page.
so finally I want some event which can detect if my Deeplink is worked or not so I can set cleartimeout function to prevent redirecting to downloading URL
I have been facing similar problem, and finally I have found a nice botched job to make it work:
var timer = null;
function setListener() {
window.document.addEventListener("visibilitychange", function(e) {
window.clearTimeout(timer);
timer = null;
window.open('','_self').close();
});
}
function redirectAndroid() {
setTimeout(function () { window.location = "https://itunes.apple.com/appdir"; }, 25);
window.location = "appname://";
}
function redirecIOS() {
setListener();
var beforeApp = new Date().valueOf();
window.location.href = "appname://";
var afterApp = new Date().valueOf();
if (afterApp - beforeApp < 100) {
setTimeout(function() {
"https://itunes.apple.com/appdir";
}, 25);
} else {
if (timer === null) {
timer = setTimeout(function() {
"https://itunes.apple.com/appdir";
}, 200);
}
}
This way, after redirecting to application, if it opens it triggers the event "visibilitychange" before the timeout function, and you clear the timeout avoiding it to redirect to web, and close the browser (if you want). If application is not installed, timeAfterApp - timeBeforeApp is not < 100 so there you set the timeout.
For desktop browser, consider using window blur listener and act accordingly
Blur listener will tell you if user left the tab or browser
window.onblur=()=>{//deeplink check (maybe unsuccessfull?)
window.onfocus=()=>{//deeplink unsucesfull};
}
I would try with a timestamp expression in the timeout.
Something like this (play around with the thresholds as needed):
var clickedTm = +new date;
setTimeout(function () {
if (+new date - clickedTm < 600) {
window.location = "https://itunes.apple.com/appdir";
}
}, 500);
window.location = "appname://";

How to detect amount of tabs for my domain?

Is it possible to detect how many tabs of my site are opened in current browser?
The problem is to restrict multiple manipulations of data to be synchonized.
I've only found how to detect for current tab: is hidden or not:
(function() {
var hidden = "hidden";
// Standards:
if (hidden in document)
document.addEventListener("visibilitychange", onchange);
else if ((hidden = "mozHidden") in document)
document.addEventListener("mozvisibilitychange", onchange);
else if ((hidden = "webkitHidden") in document)
document.addEventListener("webkitvisibilitychange", onchange);
else if ((hidden = "msHidden") in document)
document.addEventListener("msvisibilitychange", onchange);
// IE 9 and lower:
else if ("onfocusin" in document)
document.onfocusin = document.onfocusout = onchange;
// All others:
else
window.onpageshow = window.onpagehide
= window.onfocus = window.onblur = onchange;
function onchange (evt) {
var v = "visible", h = "hidden",
evtMap = {
focus:v, focusin:v, pageshow:v, blur:h, focusout:h, pagehide:h
};
evt = evt || window.event;
if (evt.type in evtMap)
document.body.className = evtMap[evt.type];
else
document.body.className = this[hidden] ? "hidden" : "visible";
//console.log(this[hidden] ? "hidden" : "visible");
}
// set the initial state (but only if browser supports the Page Visibility API)
if( document[hidden] !== undefined )
onchange({type: document[hidden] ? "blur" : "focus"});
})();
But what about total user workflow? Is there any lib what can help to detect, how many tabs are close and define "the major tab" for them?
COMMENT
A user can edit a database inside a web browser.
In order to prevent async behaviour for different tabs I want to forbid to edit the database in different tabs.
i.e.,
1. I want to define 'the major tab' there user manipulates the database.
2. If a user opens a new tabs, the site says:"I've been opened my site in another tab, please, close current tab, etc."
This is a cut down version of something I had to implement on a site, against my better judgement, because the backend code was poorly designed. So, until we fix the backend, we've put in a function like this to avoid issues where creating new records of the same type in two different tabs could cross polute the data in bizarre ways.
var pageInterlock = (function () {
var store = window.localStorage,
storeKey = false, // we actually have logic to set this to specific values depending on which page the user is on. it remains false to indicate no locking required
unlock = function () {
try {
store.removeItem(storeKey);
}
catch (e) {
}
return true;
},
lock = function () {
store.setItem(storeKey, JSON.stringify({ locked: new Date() }));
window.addEventListener('unload', unlock);
return true;
},
tryLock = function () {
var lck = store.getItem(storeKey);
if (lck === null) {
return lock();
}
return JSON.parse(lck);
},
init = function () {
var lockedOnDate,
lockData;
if (storeKey) { //you can put conditions here, for example in our system, we only prevent multiple tabs in "create" mode
lockData = tryLock();
if (lockData !== true) { // lock exists
lockedOnDate = new Date(lockData.locked);
lockedOnDate.setMinutes(lockedOnDate.getMinutes() + 1); // first minute will never be considered stale
if (+lockedOnDate > Date.now()) { // using the above lockedOnDate, you can force close if, say, the other page got the lock less than 1 minute ago, otherwise do a conditional close
// forcibly close the window if you can, or redirect to a safe page
}
else {
// in case there's a stale lock, prompt the user, close/redirect the window if the user chooses appropriately
}
}
}
};
return {
init: init // this gets called on page loaded event
};
} ());
window.addEventListener('load', pageInterlock.init); // initialise the interlock
Please note that this uses window.localStorage, so, IE8 or later only
You possibly could do this with cookies, I'm not sure really, never even considered them

How to detect browser close alone and refresh is not a part of it [duplicate]

Hi i want to detect browser refresh alone in javascript. The below code am using is detecting the browser close as well as refresh, back etc.
window.onbeforeunload = function (evt) {
var message = 'Are you sure you want to leave?';
console.log(evt);
console.log(window.event);
console.log(event);
if (typeof evt == 'undefined') {
evt = window.event;
}
if (evt) {
evt.returnValue = message;
}
return evt;
}
You can save the current time to session storage from onbeforeunload, then when the page loads look in session storage for a time and, if you find one and it's within (say) a couple of seconds, assume it's a refresh.
window.onbeforeunload = function() {
sessionStorage.setItem("left", Date.now());
};
and elsewhere, in code that runs when the page loads:
var left = sessionStorage.getItem("left");
if (left && (Date.now() - left) < 2000) {
// Refreshed
}
Full example (live copy):
(function() {
"use strict";
window.onbeforeunload = function() {
sessionStorage.setItem("left", Date.now());
};
var left = sessionStorage.getItem("left");
if (left && (Date.now() - left) < 2000) {
// Refreshed
display("Refreshed");
} else {
// Freshly loaded
}
})();

window.onbeforeunload may fire multiple times

Just because you don't see use for a feature doesn't mean it isn't useful.
The Stack Exchange network, GMail, Grooveshark, Yahoo! Mail, and Hotmail use the onbeforeunload prompt to prevent/warn users that they are leaving a page after they have begun editing something. Oh yah, nearly every single desktop program that accepts saveable user-input data utilizes this prompt-user-before-leaving UX pattern.
I have a function which behaves similarly to this one:
window.onbeforeunload = function(){
// only prompt if the flag has been set...
if(promptBeforeLeaving === true){
return "Are you sure you want to leave this page?";
}
}
When a user attempts navigates away from the page the browser presents them with the option to leave or stay on the page. If the user selects the "Leave this page option" and then they quickly click on a link again before the page unloads completely the dialog fires again.
Are there any foolproof solutions to this problem?
Note: The following NOT the solution:
var alreadyPrompted = false;
window.onbeforeunload = function(){
// only prompt if the flag has been set...
if(promptBeforeLeaving === true && alreadyPrompted === false){
alreadyPrompted = true;
return "Are you sure you want to leave this page?";
}
}
because the user might select the "Stay on the page" option which would cause future onbeforeunloads to stop working.
I think you could accomplish this with a timer (setInterval) that starts in the onbeforeunload callback. Javascript execution will be paused while the confirm dialog is up, then if the user cancels out the timed function could reset the alreadyPrompted variable back to false, and clear the interval.
Just an idea.
Ok I did a quick test based on your comment.
<span id="counter">0</span>
window.onbeforeunload = function () {
setInterval(function () { $('#counter').html(++counter); }, 1);
return "are you sure?";
}
window.onunload = function () { alert($('#counter').html()) };
In between the two callbacks #counter never got higher than 2 (ms). It seems like using these two callbacks in conjunction gives you what you need.
EDIT - answer to comment:
Close. This is what i was thinking
var promptBeforeLeaving = true,
alreadPrompted = false,
timeoutID = 0,
reset = function () {
alreadPrompted = false;
timeoutID = 0;
};
window.onbeforeunload = function () {
if (promptBeforeLeaving && !alreadPrompted) {
alreadPrompted = true;
timeoutID = setTimeout(reset, 100);
return "Changes have been made to this page.";
}
};
window.onunload = function () {
clearTimeout(timeoutID);
};
I have encapsulated the answers from above in an easy to use function:
function registerUnload(msg, onunloadFunc) {
var alreadPrompted = false,
timeoutID = 0,
reset = function() {
alreadPrompted = false;
timeoutID = 0;
};
if (msg || onunloadFunc) { // register
window.onbeforeunload = function() {
if (msg && !alreadPrompted) {
alreadPrompted = true;
timeoutID = setTimeout(reset, 100);
return msg;
}
};
window.onunload = function() {
clearTimeout(timeoutID);
if (onunloadFunc) onunloadFunc();
};
} else { // unregister
window.onbeforeunload = null;
window.onunload = null;
}
}
To register use:
registerUnload("Leaving page", function() { /* unload work */ });
To unregister use:
registerUnload();
Hope this helps ..

Categories