my script reads something like this:
$(window).bind('popstate', function() {
//some code
//few more lines of code
});
This function works perfectly as intended in Chrome and Safari browsers. But Firefox for some reason ignores this function and does not work as intended.
Instead of using:
$(window).bind('popstate', function() {
//some code
//few more lines of code
});
You can use:
window.onpopstate = function() {
//some code
//few more lines of code
}
As firefox is using W3C defined rules for history API, so you have to use this for firefox and it works in chrome, safari and other browsers as well.
Note that just calling history.pushState() or history.replaceState()
won't trigger a popstate event. The popstate event is only triggered
by doing a browser action such as a click on the back button (or
calling history.back() in JavaScript).
Browsers tend to handle the popstate event differently on page load.
Chrome and Safari always emit a popstate event on page load, but
Firefox doesn't.
https://developer.mozilla.org/en-US/docs/Web/Reference/Events/popstate
Are you saying Chrome and Safari fire the event on page load or when the browser's back button is clicked? If the former, it's because Chrome/Safari are out of compliance with the HTML5 specs => the event should never be fired on page load. Up-vote https://code.google.com/p/chromium/issues/detail?id=63040 to get Google to fix this.
Please do Check that if you have coded window.load() more than once OR have called .onload() more than one time. This probably may work for IE but not for Chrome and fireFox.
Related
I have added code to change web page color on beforeunload event:
window.onbeforeunload = function (){
$('.navbar-collapse').css({background: 'blue'});
console.log("Hello unload");
return null;
}
This code works properly on Chrome and Firefox but it doesn't work on Safari browser.
However, when I debug this code in Safari, when stepping over each line of code in the callback function, id DOES changes background color.
When I navigate by clicking on an url on page and then click back button on browser, the background color is changed.
Any idea?
window.onbeforenload is "magic" in the sense that it is special and more and more browsers are restricting what it can do.
Some browsers will let you display a custom message, other browers are free to ignore this event entirely.
In short: Don't try to do anything but return a null or non-null value and hope for the best. It is out of your hands.
You might want to see this answer too: window.onbeforeunload and window.onunload is not working in Firefox , Safari , Opera?
I'm trying to detect hashchanged which works fine in every browser except chrome. For example, with this code:
if ("onhashchange" in window) {
alert("The browser supports the hashchange event!");
}
The statement is never executed in Chrome but works in Firefox. I've seen a jQuery hashchange plugin on GitHub but didn't have any luck with that either.
Any ideas?
I have page that is doing the routing on clientside, using history API & push/popstate. Which works just fine on all the modern browsers. (search engines will be supported by node.js prerenderer)
However, I recently bumped into issue where IE doesn't fire popstate on hashchange while, while pushstate with urls works just fine, including IE11.
For example, like so...
$(document).on('click', 'a', function(e) {
e.preventDefault();
History.pushState({}, '', $(this).attr('href'));
});
...which correctly fires...
$(window).on('popstate', function() {
console.log('url changed');
});
According the W3C spec, the hashchange should fire popstate as it's changing the current history. However, when I add in hash links (<a href="#hashchange">...), clicking that on IE, nothing fires. :/
I wouldn't want to do IE detecting (as nowadays there are so many browsers which might fall in to the same pit of doom), rather than using feature detection. However, as history (popstate/pushstate) works just fine the rest of the way I can't even detect the issue on missing push/popstate...
if(!window.history || !window.history.pushState) { ...
... and use the hashchange instead. :/
Any thoughts?
PS. As a bonus, using jquery.history.js (jquery wrapped version of history.js) with hashtag url blows the whole thing up.
http://localhost/routetest/index.html#/page1/1234
becomes
http://localhost/page1/1234
... ??? :/
This is a known issue in IE11 and all Internet Explorer browsers before Edge.
See this link https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/3740423/. The Microsoft response is the last post in this issue report, and notes the newest version that is working.
All versions of IE will display this behavior, and hacking/monkey-patching the correct behavior back into the event framework is probably the only way to make it work reliably. This means you will likely need IE specific logic if you want to implement it yourself.
Try using a polyfill for History API for better support https://github.com/browserstate/history.js
In IE 10 and 11 the popstate event will only be fired for a history item after the state has been set with history.pushState or replaceState, including when it is set to null, and only when traversing between two items that have had state set. Therefore, it is necessary to set the state for a new history item in the hashchange event. Once the state is set, the popstate event will fire when the user navigates through the browser history.
https://developer.mozilla.org/en-US/docs/Web/API/History
In my web application, I launch a desktop application using a custom url protocol. For example: "fakeproto://" will launch "fakeproto.exe" on your desktop. If you don't know what I'm talking about, read this: Registering an Application to a URL Protocol
I needed a way, though, to make sure "fakeproto.exe" was installed on the user's PC before attempting to launch. It's a bit of a hack, but I got it to work for all the major browsers. IE presented the most problems and had a unique implementation.
In Javascript, I would first try to load the custom url protocol:
window.open('fakeproto://', '_self');
Before this, I actually defined the following onunload event handler:
window.onunload = function()
{
window.open('help.php', '_self');
}
So if the desktop didn't recognize the custom url protocol, IE would simply leave the current page and go to "webpage cannot be displayed". In this event, the onunload event handler would fire and open help.php instead.
This works great in IE7 & IE8, but once I upgraded to IE9, this no longer works? It goes to "webpage cannot be displayed" instead of help.php.
Using a debugger, the onunload event handler is firing and the code is being executed correctly, but for some reason the window.open call isn't working??? I disabled the pop-up blocker as well, to make sure it wasn't that. No luck.
Anyone have any ideas? Anyone hear of IE9 being more strict with window.open? Anyone know of any alternative solutions to the original problem?
BTW, I can get it to work if I open help.php to a new window.
window.onunload = function()
{
window.open('help.php', '_blank');
}
But this only works if any pop-up blockers are disabled. I would like to avoid using this solution.
Yes, IE9 blocks navigations in the onunload handler.
Does anyone know if the onbeforeunload event is supported on the iPad and/or if there's a different way to use it?
I've tried pretty much everything, and it seems like the onbeforeunload event is never triggered on the iPad (Safari browser).
Specifically, this is what I've tried:
window.onbeforeunload = function(event) { event.returnValue = 'test'; }
window.onbeforeunload = function(event) { return 'test'; }
(both of the above together)
window.onbeforeunload = function(event) { alert('test')'; }
(all of the above functions but inside <body onbeforeunload="...">
All of these work on FF and Safari on the PC, but not on the iPad.
Also, I've done the following just after loading the page:
alert('onbeforeunload' in window);
alert(typeof window.onbeforeunload);
alert(window.onbeforeunload);
Respectively, the results are:
true
object
null
So, the browser does have the property, but for some reason it doesn't get fired.
The ways I try to navigate away from the page are by clicking the back and forward buttons, by doing a google search in the top bar, by changing location in the address bar, and by clicking on a bookmark.
Does anyone have any idea about what's going on? I'd greatly appreciate any input.
Thanks
This bit of JavaScript works for me on Safari and Chrome on ipad and iphone, as well as desktop/laptop/other browsers:
var isOnIOS = navigator.userAgent.match(/iPad/i)|| navigator.userAgent.match(/iPhone/i);
var eventName = isOnIOS ? "pagehide" : "beforeunload";
window.addEventListener(eventName, function (event) {
window.event.cancelBubble = true; // Don't know if this works on iOS but it might!
...
} );
I have found that the onunload() event does fire. It's behavior is somewhat odd; whatever you have in your callback function attached to the event is actually run after the new page has loaded in the background (You can't tell it's loaded yet, but server logging will show that it has).
More oddly, if you have a confirm() call in your onunload(), and the user has clicked a link to go somewhere else, you are in business. If, however, the user closes the iPad Safari browser tab, the onunload() event will fire, but your confirm() will have an implicit cancel as response.
Only Apple would know for sure, but my guess is that they purposely did not enable that functionality in mobile Safari because it is most often used by shady characters to get you to stay on their site or pop up lots of porn/advertising windows.
There's a known bug in WebKit with onbeforeunload. I believe it's fixed in the latest beta of Chrome 5, but it's quite possible the iPad's browser is made from a version of WebKit that doesn't have the fix.
Related Chrome bug report.
beforeunload event is not supported by Mobile Safari. You can see the list of all supported events here: Handling Events Apple documentation
And the beforeunload is not in the list!
https://code.google.com/p/chromium/issues/detail?id=97035
see hear.
alerts are no longer allowed during page dismissal events (beforeunload, unload, pagehide).
I think alerts, prompt, confirm, and other actions like these are also no longer allowed.
Here's a solution that should work on all modern browsers:
var unloaded = false;
window.addEventListener("beforeunload", function(e)
{
if (unloaded)
return;
unloaded = true;
console.log("beforeUnload");
});
window.addEventListener("visibilitychange", function(e)
{
if (document.visibilityState == 'hidden')
{
if (unloaded)
return;
unloaded = true;
console.log("beforeUnload");
}
});
Mobile browsers don't tend to not support beforeunload because the browser can go into the background without unloading the page, then be killed by the operating system at any time.
Most desktop browser contain a bug that causes visibilityState to not get called when the document unloads. See: here.
Therefore, it's important to include both events to cover all scenarios.
NB
I have used console.log instead of alert in my example because alert will get blocked by some browsers when called from beforeunload or visibilitychange.
If you just need to know if the page has been left you can use document.unload. It works fine in ios browsers. If you see on Apple documentation you'll find that it's deprecated and they recommend to use document.pagehide