Handling user navigation with AJAX - javascript

I have a simple one page webapp that follows the the following flow of execution
Main -> AJAX Content -> Main
The user starts with the main screen, enters some input data and presses a button. This starts the AJAX content which is essentially a collection several different steps in a sequential manner. After completing all the steps, the user starts back on the main screen.
I want to handle what happens when the user presses the back button in the "AJAX Content" state. This is the state diagram I wanted-
Main (Push Main) -> AJAX Content (Pop Main)-> Main
So, when the user is in AJAX state, on back button press, user will be taken back to main screen. After completing the activity and returning to the main screen, the back button takes the user away from the site.
NOTE: All the items are just a single HTML page. I used the words "Main" and "AJAX Content" to illustrate the different screens that the user will see.
I tried implementing this functionality using Really Simple History, PathJS and jQuery BBQ. None of them was successful. I need a simple way to push and pop items onto the navigation stack and react to them when the user uses the back button.
I mostly develop for mobile platforms, where doing all this is really easy. I can't figure out how to do this for a web app. Snippets of code will be highly appreciated.

Would manually pushing history work for you? Something in the likes of:
window.history.pushState(stateObj, "Title", "URL");
It also supports some methods for navigation and the thing you should appreciate the most:
window.onpopstate = eventHandlerRef;
There's a very nice article right here: https://developer.mozilla.org/en-US/docs/DOM/Manipulating_the_browser_history
Now this is all good but somewhat dependent on your target platforms sadly - The support for the pushState method and the event is not too broad - http://caniuse.com/#feat=history - and both sites link to the History.js polyfill which has support pretty much covered. From https://github.com/browserstate/history.js :
HTML5 Browsers
Firefox 4+
Chrome 8+
Opera 11.5
Safari 5.0+
Safari iOS 4.3+
HTML4 Browsers
IE 6, 7, 8, 9
Firefox 3
Opera 10, 11.0
Safari 4
Safari iOS 4.2, 4.1, 4.0, 3.2

Related

Overlay windows does not close using back button on mobile browsers

I found something weird. Desktop and mobile browsers do not work the same way regarding back button.
I have hamburger menu overlay, when I click it, it opens (absolute position DIV). When I click on the link inside this overlay, on desktop, it goes to the new page. Back button then brings the previous page back, WITHOUT the overlay. This is my expected behavior.
But as I've seen, on mobile (at least on Chrome, but I think on others also), when I have overlay open and click on a link, I get to the new page, but with back I get to the previous page with the overlay STILL OPEN. It would be kind of ok, IF clicking back again would close the overlay, but it doesn't. It goes to the page I was before clicking hamburger menu or exit site, if that was my first thing I did...
Now I can handle this in 2 ways:
I can close the overlay when clicking on a link inside the menu. When I did that, overlay closes and I get to the next page. Back gets me back to the previous page without overlay. So far so good, BUT... on desktop, when I click and get on a new page this way, I have to click back 2 times to come to previous page. So that is not good.
I can somehow make the back button to close the overlay first and the next back would go back one page, but that seems even more dirty than the first option handling the push states etc.
As I see many sites have solved this. On mobile, clicking on link inside hamburger menu (or some other "popup" with menus) gets to a new page and clicking back goes back to the previous page with hamburger closed. Same behavior is on desktop, no need for double back click.
Does anybody know how I should manage this and if anybody knows why mobile browsers do not close the overlay in the first place when clicking inside it or is there some easy setting that I could trigger this behavior?
Yours
Jerry
This sounds like you just discovered a browser feature called "bfcache". I have experienced similar issues once and it took me hours to figure out whats going on.
The implementation is inconsistent through out browsers (as well as their mobile & desktop versions) and background requests the page made. It requires a certain amount of page optimization if a consistent history back/forward behavior is needed. I'm not 100% sure if that's the problem here as you missing a minimal reproducible example, but you might want to investigate in that direction.
One of the best guides on how to handle back/forward caching is this one from Google Developers.
Back/forward cache (or bfcache) is a browser optimization that enables instant back and forward navigation. It significantly improves the browsing experience for users—especially those with slower networks or devices.
As web developers, it's critical to understand how to optimize your pages for bfcache across all browsers, so your users can reap the benefits.
The "cache" used by bfcache is different from the HTTP cache (which is also useful in speeding up repeat navigations). The bfcache is a snapshot of the entire page in memory (including the JavaScript heap), whereas the HTTP cache contains only the responses for previously made requests.
  – web.dev

AngularJS / Javascript Links & Buttons Unresponsive on IOS

Been stuck on a nasty bug for way too long. Hoping someone out there has experienced this already. The issue is only prevalent on IOS 12+ (Iphones for sure, specifically IPhone 5 & 7 - haven't tested ipad) - Chrome or Safari. Androids work fine, all desktop browsers work fine.
Our app is using the Angular core with Angular Material & UI Router.
How to reproduce the issue:
1) click item as seen in picture
2) Arriving at the item detail page, click on back to results or browser back button:
3) The following is end result (a page where none of the links or buttons work, including ui-sref, regular links, ng-clicks):
Note that I double checked if any elements were in the way - there are not. Also, manually triggering a click via JS in the console allows it to work as intended. Super strange...
Also note that refreshing the page once it breaks allows it to function normally again. Also refreshing once in the details and then pressing back allows it to function normally.
There are no console warnings or errors.
Ideas?

From website to app to website on iOS

I'm working on an iOS app some people want to link to from their website.
While I've managed to open my app from a webpage using schemes, I wonder if, when I'm done with what I have to do in my app, I can switch back to the original website tab in safari.
To my knowledge : it is pretty straightforward to open a new page in safari from my app but I don't know if it is possible to get back to the actual original page, just like the ios9 back-to-app button would do.
I could open a new page and close it straight away with some javascript, which would probably display the original page because it's the next one in the tab list... but it doesn't feel right (does it?)
I read stuff about ios9 deep linking, still can't find anything interesting.
To achieve this is to open Safari using URLScheme. However, (afaik) Safari App doesn't have a url scheme. If the user came to your app from Chrome, than you can use its url scheme
Google Chrome has the following two URI schemes: googlechrome:// and googlechromes://
iOS 9's back to app button can't be invoked programmatically, so you can't use it as well. However in jailbreaked devices an app can mimic that, maybe that will help you http://theunlockr.com/2015/08/23/enable-back-button-ios-8-video/
I could open a new page and close it straight away with some
javascript, which would probably display the original page because
it's the next one in the tab list... but it doesn't feel right (does
it?)
It doesn't feel right at all. Because the typical behaviour for turning back to previos (or any other) application among iOS users is pressing home button twice, and selecting the app. Maybe you can simply show a message, and ask user to return Safari.

How to implement my own history stack in a single page mobile web application?

I have a single-page mobile application developed with Backbone and Zepto.
It works correctly with the back/forward buttons in the browser.
When the user navigates to a page, the new content slides in from the right as the old contents slides away to the left (and out of the viewport). I want the same thing to happen if the user presses the "forward" browser button. This all works.
I've got a class that I add to the body element navigate-back that will flip this behaviour, so when the user navigates back with the browser's back button, they see the content sliding back in from the left and the other content sliding into the right. Basically just the opposite of going forward.
I need to detect if the user is navigating backwards so I can invoke the alternate behaviour. I have tried implementing my own history stack, but I've ran into lots of problems where sometimes it marks a forward as a back navigation which ruins the visual cue. It's descended into a kludge of hacks now and probably would only embarrass me if I posted it.
What is the best way to implement my own history stack so I can detect if the user is navigating forward/back in the context of a single-page Backbone mobile application?
I don't know about backbone.js1, but I have helped develop a mobile application which had to implement exactly this behavior in html5, so I should be able go give some good advice:
First of all it's good to know that the history.pushState function exists. The big problem with it though is that it is supported up to android 2.3, but not on android 3 till android 4.0.3. As kiranvj points out correctly this can be solved by using the popular history.js library which provides a polyfill solution for the lack of the history functionality.
Now, getting to your actual problem, the way I implemented the history direction animations was by adding data to the pushState function ( history.pushState(data,title,url) ) with which I identified the logical position of the page. In my application I wasn't only limited to a horizontal bar, but in your case you would keep track of position where any new loaded page get's a position which is one higher then your current page. E.g.
History.pushState({position:History.getState().data.position+1},"Your title","Your URL");
Next, when the window.onstatechange or window.onanchorchange event triggers you observe whether the position is higher or lower than your current page (e.g. by using the history.js History.getState() function which I used above) and depending on this you decide in which direction to move (lower is to the left, and higher is to the right), as is illustrated by the image below:
You will also note that I already assumed on the first page that you have {position:1}, whereas normally the first page will have no state information. The way this can be achieved is by using history.replaceState which replaces the current empty state with a more informative state. Alternatively you can also check for an empty state on any of the previously mentioned events and if it's empty you assume it to be the left most one ({position:1}).
Hope this helps and if you have any additional questions feel free to ask.
Please note that this answer assumes you are using history.js and you would need to listen to slightly different events (such as onpopstate) and use slightly different structures (history rather than History) if you would want to build your own solution.
It is also useful to note that it is possible to build this with your own queue array which gives you a lot more control, but will not work in combination with the browser's back button. This is a big issue with browser sites, however is far easier in case you are building a cordova (a.k.a. phonegap) web application.
1 Just read about it and it appears to do some history handling of its own, which might make it more complex to integrate the technique described above.
If you're working on a true single-page app, why not you set up an array to hold history urls in a js variable (as opposed to relying on something like history.pushState and its support)?
Whenever a new page is navigated to, you can push its url into the array, whenever a "back" button is pressed, you can retrieve the url needed as far back as you want. This will work perfectly as long as you correctly discard urls when the user goes back a few steps and then navigates to a new link.
I've never tried implementing this to be used for page history, but this worked perfectly well for in-page undo-redo logic.
Update:
After further research, the approach above would not work for a page reload as it would be an action occuring outside of history handling available through JS. It would still work for tracking back/forward transitions, but such history will be lost on navigating to a url external to the app or a page refresh. David Mulder's answer seems to lack this limitation by relying on browser-level history that persists outside of the page scope.
I had the same issue when working with Zepto on mobile with single page - multiple views.
Initially I used html5 statechange and onhashchange. It all have some issues in one or other mobile device. Finally I used Zepto history plugin from here https://github.com/browserstate/history.js
It somewhat solved most of the issues. Try it, it will be useful, it handle html4 and html5 features wherever possible.
Use this thing in single page mobile application this will allow to the history and move the user to back.
function onBackKeyDown() {
history.go(-1);
navigator.app.backHistory();
}
Sammy.js's v.6.x branch (the one that relies just on hash changes) is a perfect, simplest, most browser-compatible approach to tracking history. There, history is not tracked at all, as Sammy just watches for hashchange.
Relying on "#/slide/123" allows you to support hard page reloads, and simplifies the work
Peel off the last part (slide number) on each page view, push into global. On new route, see if number is more or less than what is stored in global and do the correct (left or right) animation. If global is undefined, no animation.

Button Back in Browser with Frames (history forward don't work)

I have jsp aplication.
I want, that button Back don't work.
history.forward - not suitable, that transitions occur in frame.
In Google chrome when I go in my jsp aplication create history transitions in frame, and button Back becomes active. I need disable button Back or when button back is pressed - nothing happened. Open new windows without toolbar - ot suitable.
history.forward - good work if simple internet page.
In jsp project with frames hi does not behave predictably.
I need, than it wark in google chrome and IE (maby can write individually to each his own)
How do it?
You can't disable the browser's back button. The best you can do is write your application so that using the back burron doesn't break anything.
Try this code
<body onload="onLoad();" onpageshow="if (event.persisted) onLoad();">
because Firefox 1.5 uses in-memory caching for entire Web pages, including their JavaScript states, for a single browser session. Going backward and forward between visited pages requires no page loading and the JavaScript states are preserved.
Click here for your reference

Categories

Resources