Making hashchange Work Better on Windows Phone

Recently I have been creating single page web applications utilizing URL fragments.  Essentially this is a new twist to an old technique that has been around for a very long time. While not used as much these days I remember around a decade ago a common technique on long pages was to provide links to sections, like the link I provided to the W3C about URL fragments, notice the #h-4.1.1 fragment at the end of the URL? That tells the browser to look for a DOM element with the name property of 'h-4.1.1'. When the browser locates the element it scrolls the page so the element is displayed at the top of the page.

That technique is a bit dated these days, but as the use of AJAX has grown a new set of problems have emerged. As a use interacts with AJAX applications data is sent and retrieved to and from the server, thus changing the state of the application. As this occurs the user may want to use the back and forward buttons as if complete new pages were loaded. But since everything was changed within the existing page, pressing the back button takes the user to the actual page or site the visitor had open before the current page. This is very problematic for both the end use and application architect.

The use of URL fragments helps us solve this problem to a large degree because each time the URL's hash is changed a new entry is placed in the browser's history array. The browser also fires the hashchange event, or at least it is supposed to. A modern web application should bind an event handler to the window's haschange event to hydrate the page or view accordingly.

While I plan on talking more about single page web applications in the coming weeks today I wanted to focus on what seems to be a bug on the Windows Phone.

When I first tried out one of my single page applications in the Windows Phone Mango emulator (this was before it was available on my phone) I noticed the back button not responding correctly at all. I would have to hit back several times before the back action would actually kick in, especially on the home page. I checked and double checked everything on my phone, desktop and tablet. The only platform I could recreate this issue was in the Windows Phone emulator and my Windows Phone (then running NoDo).

Just to make sure it was not my code I tried some mobile web sites using jQuery Mobile and SenchaTouch I knew also used the single page architecture. Sure enough they were failing as well.

Without going into great detail on my fix here it is:


target = $.bbq.getState(


) ||




(target ===


) {

$.bbq.pushState({ target:








To manage my URL fragments I rely on the Back Button Query plugin. It has two important methods, pushState, where you push the values wanted in the new URL fragment. The getState method simply retrieves the desired portion of the fragment. Here I am using a parameter named target to identify the element's id I want to display.

In the sample above I get the current value of the target parameter if it is empty I then immediately push a value. '#home'. This causes the browser to essentially do a refresh and seeds the browser's history array somehow. If the target parameter has a value then the logic proceeds to hydrate that page.

Applying this fix does not seem to cause any harm to other browsers that are not afflicted with this deficiency. It does require you to handle this situation appropriately though. In other words you can't just rely on the jQuery ready method to be the place you kick off the page hydration, you must isolate it to the hashchange event handler. Which once you change your mindset to function well within a single page concept is not so hard.

I have seen a few other sites using what I think is this same technique once I became aware of the problem. This tells me there are other browsers and platforms I have not investigated where this is an issue. For me I have only been able to recreate it on Windows Phone. This does fall into the category of I don't know why, but I know this solved the issue for me. So if you know why or have a better fix, please feel free to share.

Share This Article With Your Friends!