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:
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/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With