pushState: How to prevent browser from attempting to load the page - javascript

I am trying to get a hook into the history object. Lets say http://my-site.com is the root url. If someone enters http://my-site.com/<url-fragment> is it possible to listen to the change of the fragment and fire and event associated with that in Javascript?

No.
You can use a beforeunload event to recognise that the page is being left, but you can't find out where it is going to.
You have to wait for the browser to load the new page and then deliver it from the server (well, you could load the homepage then use JavaScript to read location.href, but that would defeat the point of using the history API).

Related

Correctly handling the BFCache in react

I'm showing a loading screen (state) before redirecting to an external url (payment provider), since they tend to load for a while.
If the user chooses not to complete the payment and goes history.back() (Gesture, back button, ...) the browser pulls the page before from the BFCache, including the loading state, and the user will be "stuck" loading forever.
How would you suggest handling that? Persisted loads can be detected using the pageshow event, but I'm not sure if that is the react way to handle the case.
Persisted loads should be handled manually. In your case you should handle the
loader state based on the event property persisted from pageshow event handler.

Closing a popup window from a window the popup was not opened in using javascript

If I open a popup from a page is there a way I can close that popup from a different page?
Page1->Creates and opens popup.
Page2->Closes popup.
Since you can not keep a reference to your popup window on navigation, no you can not do this. But if you use pushState to change the url of your parent window and do not actually navigate, you can do it. Just simply by using close() method you can close that popup window
Other option is using a server side script to send the close signal to you popup window
I think any well-coded browser should run each page in a sandboxed environment, so one page should not even be aware that other pages exist or are being browsed, let alone what they do to the DOM or the javascript they run.
Therefore, any solution to allow communication from two different webpages (or the same page loaded two times in the browser), would have to go via an external mechanism. If its the same page loaded two times within the same browser, they should share their localStorage, so you could use it as a way to send messages.
If not, you can always rely on an external web service to do this. The page opening the popup would have to implement a polling service to see whether it should close it, and the page attempting to close the popup would have to make an AJAX call requesting it to the server, and wait for the other page to pull the result.
It's not as easy as one line of javascript, but if you REALLY want this feature, you could implement it.

check if a link redirects

I would like to know if there is javascript or jquery code I can use to check if a link would redirect the current page, instead of a it opening a new webpage.
I am using ruby on rails and on my site there are links that redirect and links that open a new webpage. I need js that executes when a user clicks on any of the links, if the link redirects, it should prompt a confirmation message then executes the link to redirect.
The only ways I'm aware that a link can open a new page are:
Downloading an attachment (not inline)
Running 'window.open' directly or through an event callback
Unfortunately, it can be extremely difficult to reliably determine through javascript inspection if these are going to happen. This is because you'll need to perform reflection on the event chain to check the javascript code, and you'll need to call the server (via ajax call) to check for a data attachment.
The simplest way to do this is to manually examine your own site and see where these are happening. Then modify the 'click' event to confirm before proceeding.

monitoring iframe content/status from the parent page

What methods are available to monitor the status of IFRAME page, I know there are security limits but I hope some small notification system is still possible.
My situation is that I have created a parent page that is located on customer's server, and this page has has iframe page located on my server (my domain). I need to somehow communicate a little between these two:
Can I make javascript to the parent page that can check if my iframe page has a specific string on it, or somehow make iframe page to notify the parent page?
Is there e.g. any possibility to make a timer that checks iframe content time to time?
I also accept answer how mydomain/client.page calls callback on customerdomain.intranet.com/parentpage.htm that has client on iframe
You need to use cross site JavaScript techniques to be able to do this. Here is an example.
Put another file into your server, call it helper.html, include it to your file served by customers server using an iframe. Set the src of the helper.html iframe with adding get parameters, ie. http:/myserver.com/helper.html?param1=a&param2=b, in the helper file use javascript to call method on parent's parent ( parent.parent.messageFromIframe(params) ). Which is the page on your server itself. Since helper and the container page are on the same domain it should work. The technique is popular, for instance Facebook was using it for their Javascript api.
I got information that this is possible by setting parent.location (from iframe) to have hash data like this "mydomain.com/mypage#mymessage"
By default, security restrictions in the browser will prevent access from/to the document in the iframe if it is in a different domain to the parent page. This is, of course, just as it should be.
I believe this would prevent even checking the current location of the iframe, but that's easily testable. If it's accessible, then you could poll the iframe for its location, and whenever the page in the iframe updates, have it append a random querystring parameter. Comparison of that parameter to the value from the previous poll would tell you if it's changed.
However, as I say, I suspect it's not possible.
Edit: This question suggests it is only possible for the initial src attribute: How do I get the current location of an iframe?

Ajax, back button and DOM updates

If javascript modifies DOM in page A, user navigates to page B and then hits back button to get back to the page A. All modifications to DOM of page A are lost and user is presented with version that was originally retrieved from the server.
It works that way on stackoverflow, reddit and many other popular websites. (try to add test comment to this question, then navigate to different page and hit back button to come back - your comment will be "gone")
This makes sense, yet some websites (apple.com, basecamphq.com etc) are somehow forcing browser to serve user the latest state of the page. (go to http://www.apple.com/ca/search/?q=ipod, click on say Downloads link at the top and then click back button - all DOM updates will be preserved)
where is the inconsistency coming from?
One answer: Among other things, unload events cause the back/forward cache to be invalidated.
Some browsers store the current state of the entire web page in the so-called "bfcache" or "page cache". This allows them to re-render the page very quickly when navigating via the back and forward buttons, and preserves the state of the DOM and all JavaScript variables. However, when a page contains onunload events, those events could potentially put the page into a non-functional state, and so the page is not stored in the bfcache and must be reloaded (but may be loaded from the standard cache) and re-rendered from scratch, including running all onload handlers. When returning to a page via the bfcache, the DOM is kept in its previous state, without needing to fire onload handlers (because the page is already loaded).
Note that the behavior of the bfcache is different from the standard browser cache with regards to Cache-Control and other HTTP headers. In many cases, browsers will cache a page in the bfcache even if it would not otherwise store it in the standard cache.
jQuery automatically attaches an unload event to the window, so unfortunately using jQuery will disqualify your page from being stored in the bfcache for DOM preservation and quick back/forward. [Update: this has been fixed in jQuery 1.4 so that it only applies to IE]
Information about the Firefox bfcache
Information about the Safari Page Cache and possible future changes to how unload events work
Opera uses fast history navigation
Chrome doesn't have a page cache ([1], [2])
Pages for playing with DOM manipulations and the bfcache:
This page will be stored in the regular cache
This page will not, but will still be bfcached
I've been trying to get Chrome to behave like Safari does, and the only way I've found that works is to set Cache-control: no-store in the headers. This forces the browser to re-fetch the page from the server when the user presses the back button. Not ideal, but better than being shown an out-of-date page.
Facebook remembers page state by modifying the hash identifier in the URL for ajax requests. These changes are recorded in browser history, so when the user clicks the back button, the hash changes to what it was before. So then it is implied that you will need some Javascript to monitor the has identifier and react when it is changed by the browser. Andreas Blixt has a hash monitoring script available.
This has nothing to do with the hash (#) symbol.
If you would check apple's HTTP headers, it's simply caching the page.
Using the URL hash/fragment identifier is a pretty common way to hook/remember state in a web application that relies on Ajax and DOM updates.
Check out the Really Simple History project for some ideas. It's possible to monitor the URL for changes to the hash, and rsh does this, taking into account browser differences.
For anybody running in problems with Rails and this -- your issue isn't bfcache (I thought it was) -- it's the turbolinks gem. Here is how to remove it.
Hopefully this'll save you some time and banging your head against the wall.
What you are looking for is for some type of URL hash management. The # in the url is for client side only.
When you change the state of the back with JS, then you update the data in the # of the url.
Also you add some type of polling that monitors if the hash has changed, and loads the state of the page based off the new data in the hash.
Take a look at this:
http://ajaxpatterns.org/Unique_URLs

Categories