Crossbrowser onbeforeunload? - javascript

Does window.onbeforeunload() fire in all browsers? I need a onbeforeunload functionality which is supported at least by IE6 and FF3.6.
For IE, onbeforeunload() seems only to be supported by IE9

I found a workaround for Firefox with setTimeout function because it does not have the same behaviour as other web browsers.
window.onbeforeunload = function (e) {
var message = "Are you sure ?";
var firefox = /Firefox[\/\s](\d+)/.test(navigator.userAgent);
if (firefox) {
//Add custom dialog
//Firefox does not accept window.showModalDialog(), window.alert(), window.confirm(), and window.prompt() furthermore
var dialog = document.createElement("div");
document.body.appendChild(dialog);
dialog.id = "dialog";
dialog.style.visibility = "hidden";
dialog.innerHTML = message;
var left = document.body.clientWidth / 2 - dialog.clientWidth / 2;
dialog.style.left = left + "px";
dialog.style.visibility = "visible";
var shadow = document.createElement("div");
document.body.appendChild(shadow);
shadow.id = "shadow";
//tip with setTimeout
setTimeout(function () {
document.body.removeChild(document.getElementById("dialog"));
document.body.removeChild(document.getElementById("shadow"));
}, 0);
}
return message;
}
GitHub: https://github.com/Aelios/crossbrowser-onbeforeunload

No it does not fire in all browsers. It's not supported in mobile browsers e.g. Safari, Opera Mobile & mini, Dolphin. See Is there an alternative method to use onbeforeunload in mobile safari?

Building upon Tushar Ahirrao solution this works cross browser and triggers once (Works in Firefox, Chrome, whatever)
<html>
<head>
<script type="text/javascript">
var app = {};
app.unloaded = false;
app.unload = function() {
if (app.unloaded) return; else app.unloaded = true;
// your code here
return "YO";
};
</script>
</head>
<body onunload="return app.unload();" onbeforeunload="return app.unload();">
YO
</body>
</html>
Paste above template to empty file then edit it

It's my recollection that IE was the only browser to implement onbeforeunload, but some browsers have taken it upon themselves to implement it.
Long story short, IE is about the only browser (with very finite exceptions) you'll find this event consistently in.

Then you can use both like this :
<body onunload="functionName();" onbeforeunload='functionName();' >

Related

why does this on scroll code work in the Browser and not on Mobile?

I have the following code snippet:
<script language="javascript">
var readAll = false;
$("#termo").on("scroll", function() {
if (readAll) return;
readAll = this.scrollHeight - this.scrollTop === this.clientHeight;
if (readAll) {
document.getElementById("aceitetermo").disabled = false;
}
});
This code works perfectly on the computer in both browser and mobile mode, enabling the button at the end of the scroll. However when I test on the phone by Chrome it does not run. In Mozilla it works normally.
Does anyone have any idea what it could be?

How do I handle a custom protocol not being installed on Safari still triggering the onblur event?

I have a custom protocol checker that checks if a protocol is installed.
For Safari (same as chrome) it focuses on an element, fires the protocol and listens for onblur.
However in Safari if the protocol is not installed the browser throws an alert esc popup saying: "Safari cannot open the page because the address is invalid." which in turns triggers the onblur event.
Has anyone found a better way of managing this? It can be a Safari specific solution if needs be.
//Chrome (and default for other browsers)
function checkChrome(){
bodyElement.append("<input type='text' id='focusInput' style='background: transparent;border: none;height: 0px;width: 0px;' />");
var focusBodyElement = $('#focusInput')[0], temporaryResult = false;
focusBodyElement.focus();
focusBodyElement.onblur = function () {
updateResult(true);
return;
};
//will trigger onblur
location.href = protocolStr;
//Note: timeout could vary as per the browser version, have a higher value
setTimeout(function () {
focusBodyElement.onblur = null;
if (protocolSupport[protocolStr]===null) {
updateResult(false)
}
}, 1000);
}
I've used custom-protocol-detection in the past here, though my target was all browsers.
That being said - in digging through their source, it seems their strategy is to embed the content in a hidden frame with the javascript creates.
function openUriWithHiddenFrame(uri, failCb, successCb) {
var timeout = setTimeout(function () {
failCb();
handler.remove();
}, 1000);
var iframe = document.querySelector("#hiddenIframe");
if (!iframe) {
iframe = _createHiddenIframe(document.body, "about:blank");
}
var handler = _registerEvent(window, "blur", onBlur);
function onBlur() {
clearTimeout(timeout);
handler.remove();
successCb();
}
iframe.contentWindow.location.href = uri;
}
source
The source also contains strategies for all browsers.

iOS Safari non-blocking window.print

I have a specific problem with page printing in JavaScript. I need to open my page on another tab with all scripts removed (this way: $(document).get(0).documentElement.innerHTML.replace(/<script[^>]+>.*?<\/script>/gi, '') and then call window.print() inside new tab, and close it afterwards.
That's because errors in scripts are causing problems with printing. Code responsible for the whole printing:
var w = window.open();
w.document.write(
$(document).get(0).documentElement.innerHTML.replace(/<script[^>]+>.*?<\/script>/gi,'')
);
w.document.close();
var loadingImagesInterval = setInterval(function() {
var imgs = w.document.querySelectorAll('img');
for (var i = 0; i < imgs.length; i++) {
if (!imgs[i].complete) return;
}
clearInterval(loadingImagesInterval);
w.focus();
w.print();
w.close();
}, 100);
Basically, the problem is, on iOS, w.print() seems not to block code execution until confirm/cancel in printing view and w.close() is called immediately after. All other browsers work just fine: Mac Chrome, Mac Safari, IE11, Mac Firefox. All fine. Just not iOS Safari.
I tried this code, but didn't work as well:
w.matchMedia('print').addListener(function(mql) {
if (!mql.matches) {
w.close();
}
})
Is there a better way to deal with my problem?
EDIT: iOS version 12.2 introduced a "Done" button when opening a page from the Home Screen, so there is no need for a CLOSE button as described below. It is only needed for 12.0 and lower.
I worked around this by:
detecting Safari;
adding print and close buttons and hiding them for the print;
avoiding write() because it opens a new page, and the close button will not return the user to the previous page.
Caveat:
the popup blocker might have to be deactivated in Safari's settings to prevent the alert "This website has been blocked form automaticaly printing."
// detect Safari
if (navigator.userAgent.indexOf("Safari") !== -1) {
// make print button
const print_button = document.createElement('button');
const print_button_text = document.createTextNode("Print");
print_button.appendChild(print_button_text);
print_button.addEventListener(
"click",
function() {
// hide the buttons before printing
print_button.style.display = 'none';
close_button.style.display = 'none';
newWindow.print();
// delay reappearing of the buttons to prevent them from showing on the print
setTimeout(() => {
print_button.style.display = 'block';
close_button.style.display = 'block';
}, 2000);
},
false
);
// make close button
const close_button = document.createElement('button');
const close_button_text = document.createTextNode('Close');
close_button.appendChild(close_button_text);
close_button.addEventListener(
"click",
function() {
newWindow.close();
},
false
);
newWindow.document.body.appendChild(print_button);
newWindow.document.body.appendChild(close_button);
};
And then I added the content I wanted to print. I hope this helps.

Javascript - How to get your browser in focus

I'm running a script on a retail site that when the browser is in focus, it passes every time. When the browser is not in focus, it fails every time.
My waitUntil(Waits.elementDisplayed(.... doesn't work when not in focus.
Any ideas ?
Thanks
you can detect if the browser is out of focus with the following javascript function
function onBlur() {
document.body.className = 'blurred';
};
function onFocus(){
document.body.className = 'focused';
};
if (/*#cc_on!#*/false) { // check for Internet Explorer
document.onfocusin = onFocus;
document.onfocusout = onBlur;
} else {
window.onfocus = onFocus;
window.onblur = onBlur;
}
Reference
However, i'm not sure if you always getFocus if it is out of focus. Hope this helps.

FireFox different onchange behavior than Webkit/IE

Is anyone able to explain this?
Basically when you're in firefox, and you hit tab, the "console.log" in the onchange gets called but not in Chrome/Safari (webkit) or IE.
function initLookup(id) {
var lookupElement = document.getElementById(id);
var lookup = new Lookup(lookupElement);
lookupElement.lookup = lookup;
}
function Lookup(lookupElement) {
this.doKeyDown = doKeyDown;
this.setLookup = setLookup;
this.inputElement = lookupElement;
this.inputElement.onkeydown = this.doKeyDown;
var self = this;
function setLookup() {
self.inputElement.value = 'asdf';
}
function doKeyDown(event) {
if(event.keyCode == 9) {
setLookup();
}
}
}
initLookup("one");
And a JS fiddle working example:​
http://jsfiddle.net/pj9Gf/5/
Gecko differs from IE (and apparently Webkit), in that the change event is fired after the blur event had been fired.
By setting the value on TAB key-press, you're effectively preventing the change from being applied, as the change trigger is defined by a difference between the values detected on focus and on blur.
Reference
element.onchange on Mozilla Developer Network

Categories

Resources