I have an HTML5 application that manipulates the browser history to show the proper URL for Ajax calls. This works great, but a problem occurs when my application has hyperlink to an external site, say http://www.google.com. When this happens, the history looks like this:
My App Page A -> My App Page B -> Google
When the user hits the back button once, everything is fine. My App Page B is shown.
But when the user hits the back button a second time, the URL changes, but the page doesn't change. My app can't make the proper Ajax call to show the state for My App Page A, because the onpopstate handler never got called. This is because the handler wasn't initialized when the browser went back to My App Page B (no events fire on that back event, so I can't reinitialize the handler.)
This experience is with Chrome, but I have no reason to believe it is Chrome-specific. Is there a way around this problem?
I know that applications like Gmail open all external hyperlinks in a new window. But the requirements for my application don't allow me to do that.
The link provided by #Pumbaa80 put me on track to the right answer.
If you put <body onunload=""> on your page, then is breaks the bfcache on Chrome and other browsers. This means that when you click the back button to return to My App Page B from Google, all page state JavaScript events will fire.
There is no way to get onpopstate to get called on My App Page B after coming back from Google. (This woud be illogical, as that event only fires on the page where you hit the back button.)
The alternative is to execute the logic when My App Page B loads. By breaking the bfcache as described above, jQuery dom ready will fire. By running similar code from onpopstate in a jQuery dom ready callback, I can access the data stored in the History object reset the state of my HTML5 web app after returning from an external page.
I think you'll need to use hash tags to save the state of your page, I don't see a way around this. I've done it in the past with great success using this jQuery plugin, with the very fashionable name BBQ (Back Button & Query library). This will allow your page to perform actions based on the hash tags in the URL.
Related
I am working on a web application and have pages which gets data asynchronously using ajax call during the page load. These calls does not block the user. When we inspect the page using developer tools (IE and Chrome) it seems that the timing to load the entire page takes more than 26s. Please see the image attached which shows the details of default.aspx. But even before loading the entire page, the user can interact with page.
I need to find a way to identify at which point, the user can interact with page, using some java script event api like DOMContentLoaded. But I am not sure which event is the right one which ensures the user can start interacting with the page even if it is loading data in background using ajax call. Any guidance is appreciated
.
When accessing an external page from a Cordova app, then coming back to app with back-button, the app page is empty, or more precisely, everything that was dynamically added to the page is gone.
This seems to be the case whether the link is a native <a href="..."> or is accessed via window.open(), or via cordova.InAppBrowser.open(). The only way it does not happen is when the actual browser is specified via "_system" parameter.
Is there a way to prevent this, or is it normal behaviour ? Should I simply rebuild the dynamic page upon returning ? I could do that, but no event seems to be fired on return, not even a pageshow.
Navigating back refreshes (reloads) the page...so anything dynamically added to the page will correctly be gone. You could use hash tags on the URL for simple information or localStorage for more complex information about the page state and re-populate the page based on it when it reloads.
pageshow most like isn't firing because of some assumption being made in the JS code. Try listening to the $(document).ready for debugging purposes. It could also be caused by the issue described here (because of caching): 'pageshow' is not received when pressing "back" button on Safari on *IPad"
Specifying system causes the page to open in a new window...so that's
What I got working so far:
Store a few pages in the DOM so that when the user uses the browser's back or forward button it will quickly show the page without reloading it.
What I need help with:
When a user clicks a link to a page that is already in the DOM (for back/forward functionality), I want to remove the requested page from the DOM before jqm processes the request so that the requested page is retrieved from the server rather than the DOM.
If this is possible I'm guessing I need to somehow use the pagebeforechange event.
Basically, I want jqm to use the DOM only for back/forward navigation. Otherwise I want the page to be retrieved from the server.
I am using History.js and Jquery (and a little GWT), I use the History.pushState() method to store the Ajax payload, then in the statechanged event I paint the screen according to the payload. Now inside my app the browswer back and forward buttons work correctly.
The strange thing is when users click a link in my app that takes them to a page that is outside of my app (same domain but another application), they go out, view the page, then hit the back button to re-enter my app.
My app loads, it does not receive a popstate or a statechange event, but somehow the browser is actually painting the screen to resemble exactly what it looked like before they left my app.
I'd like to understand what is happening here.
[EDIT: I was wrong. My code was executing and I did receive the statechange. I had some assumptions about History.js, and now I realize to code correctly, you should receive your AJAX payload, then call pushstate to put it on the stack. Then your statechange event will fire, and you should, in the statechange function, read the state off the stack and paint the screen accordingly. The same code will execute when you run your app normally, and the same code will execute when the user hits the back button. ]
You have to read the URL and then handle accordingly. It's the same as if you were deep linking into your application directly from the address bar.
It sounds like the browser is showing a cached state of the app instead of completely reloading it when the user uses the back button to return to the app.
You can test this by going into the app, clicking the outside app link, hitting the browser back button to go back, and then hitting refresh. If it changes the app state upon reload, it tells you that the browser was caching the app state instead of reloading.
A website contains a "random" link, which loads a url that returns a 307 redirecting to the url we want. It works fine: click it and you load a random page. The problem is that each time you click it, the browser assumes you're loading the same page: so if you're on the homepage, then you follow the random link 5 times, then you press back, you'll be taken all the way back to the homepage, with no way to find the random pages you were just looking at. I want to modify this behavior so that users can access previous random pages via the back and forward buttons.
I don't own the website, so I can't just change the redirect code.
Here's what I've tried, all of which has failed.
Predicting what would be redirected to. While somewhat possible, there would be no way to avoid failure in up to .1% of clicks, and it would react very poorly to unexpected events, like a page that's published a day late, let alone a sit structure change.
Loading the 307 page via ajax. The request stops at readystate == 2 and I can't access the location header.
Cancel the click event and instead set location.href = random_link.href. This has no effect - the new page still doesn't go into history.
Have the new page call history.pushState. This successfully adds the page to history, but I can't find a way to distinguish between new pages and ones being opened via the back button, so the history quickly becomes very corrupted.
Keeping my own history in localStorage. As above, I can't tell when the back button is being used.
I'm working on a solution that I'm pretty sure will work, involving loading the page in an iframe over the existing page and using a background process and messaging to work around the fact that content injections from chrome extensions can't access window.parent from within iframes. And using the history API to reflect the current iframe's URL in the address bar, and get the back and forwards buttons to apply to the current iframe where appropriate.
While I'm pretty sure the last solution can be made to work, it's a hideously complex and heavyweight approach to what seems like a simple problem. So I thought I'd ask you guys before I continue: any other ideas?
Have you tried storing the locations in localStorage, then hi-jacking the back button ?
I am sure you know how localStorage works, for hi-jacking the back button you can refer to this : Is there a way to catch the back button event in javascript?
T.