Differences in Internet Explorer and Firefox when dynamically loading content then going forward and back - ajax

I'm developing a web application where, due to slow database access, not all content in a page is loaded immediately but rather dynamically when the user clicks a button after optionally making a selection.
This works fine. However, after dynamically loading content, if I navigate to a different web page, then navigate back, in Internet Explorer the loaded content will have disappeared, i.e. the page will have reverted to the originally retrieved page. In Firefox (and Opera as well), however, the loaded content will still be there, i.e. the page will look like it did before I navigated away from it.
The Firefox behaviour is the desired behaviour in my case, as the user would routinely navigate to subpages and go back to the main page. My question is therefore, is there any way I can force Internet Explorer to exhibit this behaviour, or are there any possible workarounds to get the desired result?

Here is my workaround solution for IE. It utilizes the fact that, even if the DOM is reset when navigating away and back to a page, input field values are still remembered.
For every dynamically loaded element, I also have a hidden input field where I "cache" the loaded value. I then have a function transferFromCache() which copies the values from each hidden input field to the corresponding element. This function is run at page init - which, in IE's case, is at page load AND every time one navigates back to the page.
This technique could probably be used to store the values of javascript variables as well.

I don't think there's a method to get IE to emulate FF in this manner. The reason is to do with fairly fundamental aspects of the browsers. FF uses a mechanism for it's page history called 'Fast DOM caching' which (from my limited understanding) basically means that when it puts a page into the browser history then it will store the current DOM (so the current page state) in a serialised format, which means that when the page is reloaded from history the state is preserved and FF can do this much quicker as a lot of work is already done (parsing the HTML into a DOM, etc). In comparison, IE will simply store the HTML received initially as it's history file and will reload it when navigating history.

Here is an article about saving state in session variables, which may help

Related

CKEditor (in a SPA) freezes when navigating back to the editor page

I'm trying to integrate CKEditor in a page of a SPA (Single Page Application).
CKEditor behaves correctly within the SPA page on the first visit, but not on next visits. For example, when pressing the backward browser arrow (to display the previous SPA page) and then the forward arrow (to display again the SPA page with CKEditor), CKEditor appears but the content has been erased and it's not reacting anymore. There is no carret when cliking on the text area. Also all API calls (such as setData() or resize()) have no effect anymore (whereas they were working on fist visit).
I presume CKEditor doesn't like its element to be removed from the DOM (that's what happens when switching to another page) and then be re-added to the DOM (that's what happens when visiting the page again).
EDIT ON July 5 2017
Thanks for your proposition to destroy CKEditor when leaving the page and to recreate it when navigating back, but this causes the lost of the editor state such as the the scrollbar position, the caret position, text selection, etc...
Ideally I would like to make it possible for a user to visit another page while he is in the middle of writing something in the editor (for example to check an information or copy a content from another page) and then to continue exactly where he was (no change on scrollbar, caret, selection,...) when he navigates back to the editor.
Is is possible?
Removing CKEditor just by removing its parent container like in your fiddle is not a good solution as CKEditor attaches some listeners to the DOM and by removing the container you are detaching those listeners which are not reattached then.
You should destroy the editor before removing from DOM and then recreate it. Remember that destroying happens in an async manner so to know when it is finished you may listen to destroy event.
Here is modified fiddle using destroy method (without handling destroy event which should be added).
EDIT ON July 10 2017
To preserve the state of the editor (scrollbar position, text selection, etc) between destroy - recreate, state of all this elements should be retained before destroying editor and then set after recreating it. It is doable, but requires some work and quite a lot of custom code.
Ideally I would like to make it possible for a user to visit another page while he is in the middle of writing something in the editor
Since you are creating a SPA application, for the above the better solution will be to use some floating/fixed container in which CKEditor is placed and which does not reload with rest of the page upon navigation (e.g. the same as Facebook chat works).
Also remember that recreating CKEditor takes some time (very short, but it may be still visible) so on every page navigation it will be visible for the user that something is happening with the editor even though its state does not changed.

Content Script Injection at Install for Firefox Web Extension

If content scripts are specified in manifest.json for Firefox, Firefox will also load content scripts for already opened tabs and execute them even the tabs are already in loaded and ready state.
Google Chrome does not add any content script when extension is installed for already opened tabs. The content script is loaded when the page is refreshed for the older tabs.
I want to ask is Firefox's behavior is expected or bug?
As far as compatibility goes, it's a bug.
Chrome does not do that.
As a result, many extensions implement custom logic to achieve the effect.
One has to take into account side effects. Suppose your content script injects some UI into the page. Then the extension is updated. That amounts to extension restart, and suddenly you have 2 copies of the UI. Also valid if you just attach event listeners, as (at least in case of Chrome) the old content script's context continues to exist (in an "orphaned" state).
The last point is very important and probably the reason why Chrome doesn't do it by default. At some point I made a very long post about this problem - if you're going to report this as a bug to Mozilla, please include that. There's also this feature request that is related.
What would be sensible (and backwards compatible) is to add a parameter to content script description in the manifest - whether to inject into existing pages. It will be up to developers to guarantee that side effects are taken care of. This usually requires even more code to just communicate to the old script that it needs to wind down and clean up.

Lock Firebug to a specified page

Is there a way to keep Firebug on a single page, so that when I switch pages it remains on the page I want it set to?
For example, I'm working on a project and I get an error that I want to search for on Stack Overflow, but when I navigate here, the console changes to reflect this site. I'd like to stop that from happening.
There is no option to "pin" a page's data in Firebug (as of version 2.x). As far as I know this also doesn't work in any of the browser built-in dev tools.
Though the simple solution for your problem is to open the other page in a separate tab or window. Doing so keeps all the data of the page saved when you switch back to the tab containing your project's page.
Note that Firebug's activation model is based on URLs following the same origin policy. I.e. if you open it for your project's page, it will always get opened for your projects page, even on other tabs, but not for any other site.
I've found it useful to split the tab of interest off into a new window and to activate Firebug on that window. That way I can continue using my original tab collection/window without it changing as I link-hop.

Firefox back button vs iframes

In Firefox if the window.location of an iframe is changed, this gets populated to the history of the top level window.
If the user now clicks the browser back button, the contents of the iframe will change rather than the browser going back to the previous HTML page.
This is totally wrong for some architectures.
Is there any way with JavaScript to prevent Firefox (3.x) from doing this?
(Please stick to just this question, not why/when/how iframes versus other techniques should be used.)
Use .location.replace
I have the same issue and was researching possible ways around it when I read this. I don't know if you solved the problem, but I think I'm going to use the unload event in the IFrame'd window to notify the parent window when it's unloaded.
If the iframe is closed by a 'valid' method, a variable is set at the parent to say the iframe is expected to unload
If the parent reloads / changes the src of the iframe a variable is set to say the unload is expected
If an unexpected unload happens in the iframe I assume it was the back button and update the parent page accordingly (e.g. jump another step back in the parent's history, or do something else).
The only ugly case here is if the parent page is unloaded and the iframe also throws unload - depending on how quickly the parent page changes you might get a race condition where the parent's iframe unload handler is or isn't fired.

How do you serve a file without leaving the page?

Aims
I'm trying to let users download a file (myfile.zip in this case) by clicking a button on the page, without them leaving the page - ie the browser must stay on the current page, and leave them in a position where they can continue to use the page, including clicking the button again (should they wish to get a new copy of the file).
I need this to work across all browsers (IE6-8, Firefox, Chrome, Opera, Safari).
Background
Packaged inside the zip is a selection of stuff based on their other interactions (some of which may be partially complete) from the same page (this is all done via ajax) and I don't want them to leave the page as they would lose any unsaved changes.
Add the following header when the download file is served:
Content-disposition: attachment; filename=filename.zip
Most browsers will wait to see what type of thing they are loading before they clear the current page, and if it something that should be downloaded as a file they won't navigate away from the current page (they'll show a Save As dialog in front of the page, which can be dismissed to return to the page).
If however you find that a certain browser does navigate away from the current page, you may try having the link to the download contained in a small iframe, so only that frame changes.
I think it's a better solution to opening the link in a new window, because some browsers will leave the new window up even once it's determined that it is a file that should be downloaded, so you end up with a blank window.
If you make the link open in a new window/tab (e.g. via the <a> tag's target="_blank" attribute), it won't disturb the contents of the current window.
The target attribute is deprecated, but widely supported. Depending on the browser, you may also be able to use the CSS3 target-name property.
If your goal is to absolutely guarantee that the main window is undisturbed, this is likely the safest method, as it's resilient against download errors.
To avoid leaving the page (if you do this the page tries to close itself first, so that it's sure that you've saved everything, and you get warning messages if you haven't) or leaving blank tabs (which I don't like, nor the use of the depreciated target attribute) I've used an iframe, whose src attribute is changed in javascript.
This works everywhere except some versions of Opera, which I have considered an acceptable loss (I might fix that via the use of one of the other solutions plus browser detection later).
I believe if you direct the user to a file and the MIME type is something the browser knows it must download vs render, the browser will not leave the page. For instance if you were serving a zip file the browser would know it was a zip file and prompt for download. But if you were going to serve a zip file from a page request (i.e. /file.aspx?file=myinfo.zip) then file.aspx would need to change the MIME type to be "application/zip" before send back the response in order to prompt the user for the download.
One major caveat here is if the file didn't exist for some reason the user would get a 404 and be directed to the error page.
As a sure-fire way of not redirecting the user you could open a pop-up for downloading.
We do this on postback on an aspx page by setting ContentType to "application/octet-stream", then streaming the zipfile with Response.BinaryWrite(..) and Response.Flush().
Gives the user a popup "do you want to open or save" the file.
Page is still available.
By the way, specifying the appropriate content disposition header alone might not work in all browsers. Specifically, I've seen it not work in Opera, and IE7 displays the yellow security warning bar.
In addition to the appropriate header, as described by thomasrutter, The way I've done this is by using a hidden form:
<form id="download_form" method="get" action=""></form>
When the user clicks a button, you can manipulate the "action" attribute of the form with the URL of the file.
This seems to work in all browsers, even IE7!

Resources