I have tried to type this code into the browser's console:
window.onpopstate = function() {alert(1);}
and then click the back button. No alert has shown.
Am I doing something wrong? Or is it not allowed to bind popstate event to a page from console?
Using Chrome 24 and Firefox 18
Type this into the console
window.onpopstate = function() {alert(1);}; history.pushState({}, '');
then click the back button.
I prefer adding the popstate listener as follows, to prevent overwriting of what's already in window.onpopstate:
window.addEventListener('popstate', function(){alert(1);});
Related
I am now trying to detect only the event of the browser close button of IE11 in JavaScript.
I was able to detect the browser close button with the onbeforeunload event, but I also have trouble picking up other page transition events.
This code is I trying on it.
window.onbeforeunload = function(event) {
alert('Sure you want to close ?');
}
Is there any good way to do it ?
Try using the addEventListener syntax:
window.addEventListener('beforeunload', function(){
alert('Sure you want to close ?');
});
Actually the onbeforeunload Event will be fired when you close the browser/tab , refresh the page(or F5), submit a form, or jump to other pages..etc
AFAIK, there is not a perfect way to detect which operation exactly USER do.But for your question, i guess there are some html tag like
To ABC
that fired the onbeforeunload Event when they are clicked. If it is true, may be you can remove the Event when the HREF was active so that the Event would not be fired.
Try codes blow:
<script type="text/javascript">
$(function() {
$("a").click(function() {
window.onbeforeunload = null;
location.href = $(this).attr("href");
return false;
});
});
window.onbeforeunload = function(e) {
return 'Sure you want to close ?';
}
</script>
Note that this would not prevent the refresh opreation to fired the onbeforeunload Event, but i hope to provide some ideas for resolving your problem.
Firefox is firing onchange events in my webapp after tab restore.
When reloading the same URL in Firefox there is no problem, no onchange events get fired on page load, all changed values since last visit are displayed correctly.
But when reopening the same page with the same URL, after closing Firefox and reopening the page with "restored tabs" (from the Firefox option "show my windows and tabs from last time") then it is firing onchange events for all values that have been changed since last visit.
Actual workflow ot reproduce the problem:
My update events are in background (JavaScript/AJAX) and are fired
with onchange events;
Firefox setting "show my windows and tabs from last time" enabled;
Change some values in my page (select fields);
Close Firefox;
Open the same URL on another browser or computer, and change some values;
Reopen Firefox, select the tab with the page on it, it reloads and fires onchange events again for all changed values since last visit.
Tried to reproduce this behaviour with completely different pages (not created by me and using other script libraries and stuff) and the result is the same, it is always firing the onchange events.
Chrome is not doing this with the "restore tabs" option.
Why is it firing onchange events? How can I prevent it?
A few suggestions on how to deal with this depending on the wanted result. Note that this is tested on my machine, behaviors may vary.
They way it seems to work is that Firefox tries to restore data that was entered by user. So it modifies the page, triggering the change event. This event is slighlty different than the one triggered by the user. It is a UIEvent while the user triggered one is a straight Event. And this Event is cancelable and triggered before the window load event. So this gives a couple of ways to deal with this. I'll take a select element for example.
If you want the select to keep value entered before window closing, but not trigger the onchange event, you can set the onchange call on the window.onload. Like this:
window.onload = function(){
element.onchange = function(){
Since the setting of the select occurs before onload, this specific change won't trigger your onchange function.
Other way would be to target behaviors you don't to trigger by putting a condition validating if the element is cancelable or not. If it's cancelable, it means it's called from a restore session and won't trigger what's inside. Like this:
element.onchange = function(e){
if(e.cancelable == true){
Other way, to clear out all data would be to set a document.onchange event and reload the page if the event is cancelable. Like this:
document.onchange = function(e){
if(e.cancelable == true){
window.location = window.location
}
}
Of course you need to make sure you don't have any other cancelable change event called in your page.
EDIT:
To clarify order of events fired, see this jsfiddle, not in iframes, iframes seems to behave differently, so if you have iframes, it may be a bit more complicated. But without iframe, you'll see how the different events are triggered depending on your interactions:
document.onchange = function (e) {
//this will be triggered on restore before the window load event
alert('restore onchange called, e.cancelable = ' + e.cancelable)
}
window.onload = function (e) {
//You'll see that on restore, this will be triggered but after page has been updated
alert('window load called')
document.onchange = function () {
//This onchange will be called normally, not on restore
alert('after onload change, e.cancelable = ' + e.cancelable)
}
}
http://fiddle.jshell.net/nozp9uhk/6/show/
Firefox is caching your files when you load the page, so when you restore the tab, the differences between your cached values and the new ones may be firing onchange events.
Try to clear the cache when restoring the tab. I see two ways to do this :
Call window.location.reload(true) to reload the current page
or
Change the name of the JavaScript file that initializes the onchange events for this :
<script language="JavaScript" type="text/javascript" src="yourscript.js?n=1"></script>
This (?n=1) will force Firefox to load a new copy of the file "yourscript.js"
I've tried a few methods to see if I can create a cross browser solution for delaying a popstate event but have not had any luck.
Anyone have any ideas or thoughts?
Below obviously does not work, but something to the effect of:
$(window).on('popstate', function(e) {
// something here to delay the history pageload
console.log('a wild console has appeared!');
});
So the flow would follow this sequence:
Browser "back" or "forward" button clicked
run initial code
A delay before the page changes
page change
According to the Documentation the popstate event is
only triggered by doing a browser action such as a click on the back button
So I do not believe it will get triggered when user clicks 'forward' (and it varies in some browsers)
For reference, here's the full text:
The popstate event is fired when the active history entry changes. If the history entry being activated was created by a call to history.pushState() or was affected by a call to history.replaceState(), the popstate event's state property contains a copy of the history entry's state object.
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 (prior to v34) and Safari always emit a popstate event on page load, but Firefox doesn't.
UPDATED ANSWER ABOVE
Your code works. (see below) - I added an element to trigger the event (you can see the results in the console)
Make sure you include the jQuery library on your HTML prior to using it though.
$(window).on('popstate', function(e) {
console.log('fired instantly!');
var timer = setTimeout(function() {
console.log('delayed popstate!');
clearTimeout(timer);
}, 1000);
});
$(window).trigger( 'popstate') ;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I have a simple code to test the history api of html5
Just some buttons
<button name="hey1" onClick="historytestone();">history test one</button>
<button name="hey2" onClick="historytesttwo();">history test two</button>
<button name="hey3" onClick="historytestthree();">history test three</button>
<button name="hey4" onClick="historytestfour();">history test four</button>
<button name="hey5" onClick="historytestfive();">history test five</button>
and my js is like
function historytestone(){
history.pushState({page: "ross"}, "ross","ross.html");
}
function historytesttwo(){
history.pushState({page: "monica"}, "monica","monica.html");
}
function historytestthree(){
history.pushState({page: "chandler"}, "chandler","chandler.html");
}
function historytestfour(){
history.pushState({page: "joy"}, "joy","joy.html");
}
function historytestfive(){
history.pushState({page: "rachel"}, "rachel","rachel.html?a=1&b=2");
}
// this does not work
window.addEventListener("popstate", function(event) {
alert("hello");
});
//nor this works
window.onpopstate=function(event){
alert("hello");
}
When I try to listen for the popstate event, I get no alert and no errors on the console. No metter what syntax I use, I get nothing.
Sorry, but I cannot see what is wrong. Please explain.
EDIT
Here is my problem.
This is my code here and this is the demo I was based here.
Now, I believe that my code is a simplified version of the demo.
I have to click the "back" button of the browser in order to fire the popstate event (see the alerts). But the demo can fire the popstate event (change content) just by clicking the names.
Why this happens? Why I have to hit the back button and the demo does not, even tho is the same code? Thanks again
based on the definition here: https://developer.mozilla.org/en-US/docs/Web/Events/popstate
The popstate event is fired when the active history entry changes. If
the history entry being activated was created by a call to
history.pushState() or was affected by a call to
history.replaceState(), the popstate event's state property contains a
copy of the history entry's state object.
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.
if you see the source code of http://html5doctor.com/demos/history/ each time when you click a link it calls the updateContent function (which is also the event handler of popstate) then it calls pushState.
I'm having a problem with a 'popstate' event handler, this is my code:
window.addEventListener("popstate", function (event){
if (event.state) {
alert('abc')
}
});
// The data object is arbitrary and is passed with the popstate event.
var dataObject = {
createdAt: '2011-10-10',
author: 'donnamoss'
};
var url = '/posts/new-url';
history.pushState(dataObject, document.title, url);
I expected this code will pop up an alert box when it's executed but, nothing happens.
Is there anything wrong here?
Thank you.
pushState do not trigger the popstate event, only clicking back / forward button (or use backspace) or invoking history.back() / history.go(n) would trigger this event.
Also, in webkit browsers, a popstate event would be triggered after page's onload event, but Firefox and IE do not have this behavior.
No it will not,
As per MDN documentation
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).
Again as per this question the popstate event is not triggered in Chrome when you call pushState().
history.pushState() will not trigger the popstate event by definition.
The popstate event is fired in certain cases when navigating to a session history entry.
This event is intended to be only triggered when navigating to a history entry, either by pressing the back/forward button, or history.go/back.