Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is monitoring location.hash a solution for history in XHR apps?

As is well known, in XHR (aka AJAX) web applications no history for your app is build and clicking the refresh button often moves the user out of his/her current activity. I stumbled upon location.hash (e.g. http://anywhere/index.html#somehashvalue) to circumvent the refresh problem (use location.hash to inform your app of it's current state and use a page load handler to reset that state). It's really nice and simple.

This brought me to thinking about using location.hash to track the history of my app. I don't want to use existing libraries, because they use iframes etc. So here's my nickel and dime: when the application page loads I start this:

setInterval(
       function(){
           if (location.hash !== appCache.currentHash) {
               appCache.currentHash = location.hash;
               appCache.history.push(location.hash);
               /* ... [load state using the hash value] ... */
               return true;
           }
           return false;
       }, 250
 );

(appCache is a predefined object containing application variables) The idea is to trigger every action in the application from the hash value. In decent browsers a hash value change adds an entry to the history, in IE (<= 7) it doesn't. In all browsers, navigating back or forward to a page with another hash value doesn't trigger a page refresh. That's where the intervalled function takes over. With the function everytime the hash value change is detected (programmatically, or by clicking back or forward) the app can take appropriate action. The application can keep track of it's own history and I should be able to present history buttons in the application (especially for IE users).

As far as I can tell this works cross browser and there's no cost in terms of memory or processor resources. So my question is: would this be a viable solution to manage the history in XHR-apps? What are the pros and cons?

Update: because I use my homebrew framework, I didn't want to use one of the existing frameworks. To be able to use location.hash in IE and having it in it's history too, I created a simple script (yes, it's needs an iframe) which may be of use to you. I published it on my site, feel free to use/modify/critizise it.

like image 673
KooiInc Avatar asked Feb 20 '09 08:02

KooiInc


1 Answers

There are 3 issues that tend to get munged together by most solutions:

  1. back button
  2. bookmarkability
  3. refresh button

The window.location.hash based solutions can solve all three for most cases: the value in the hash maps to a state of the application/webpage, so a user can press one of "back"/"forward"/"refresh" and jump to the state now in the hash. They can also bookmark because the value in the address bar has changed. (Note that a hidden iframe is needed for IE related to the hash not affecting the browser's history).

I just wanted to note however that an iframe only solution can be used without monitoring window.location.hash for a very effective solution too.

Google maps is a great example of this. The state captured for each user action is way too large to be placed into window.location.hash (map centroid, search results, satellite vs map view, info windows, etc). So they save state into a form embedded in a hidden iframe. Incidentally this solves the [soft] "refresh" issue too. They solve bookmarkability separately via a "Link to this page" button.

I just thought it's worthing knowing/separating the problem domains you are thinking about.

like image 62
Crescent Fresh Avatar answered Sep 18 '22 14:09

Crescent Fresh