HTML5 History API

April 5, 2013

HTML5The Ext JS framework includes the Ext.util.History component for managing the browser history that was first introduced in Ext 2.0 back in 2007. It’s pretty solid, and other than bug fixes it hasn’t changed much since then.

In the reportcaster framework, all state changes while changing reports or drilling within reports is routed through a Navigator component that supports pluggable strategies for how to do that navigation. The default method is to use the browsers history. We were using Ext.util.History to do that and it worked just fine. However, since Ext.util.History doesn’t support the hashchange event or HTML5 History all navigation is slightly delayed by the polling interval of Ext.util.History.  Users found that to be undesirable.

history.js

The history.js project is a mature, cross browser implementation of the HTML5 History API that implements all the latest History features using native functionality when available. It also gracefully downgrades to support HTML4 browsers, all the way back to IE6.

From the project page:

  • Follow the HTML5 History API as much as possible
  • Provide a cross-compatible experience for all HTML5 Browsers (they all implement the HTML5 History API a little bit differently causing different behaviours and sometimes bugs – History.js fixes this ensuring the experience is as expected / the same / great throughout the HTML5 browsers)
  • Provide a backwards-compatible experience for all HTML4 Browsers using a hash-fallback (including continued support for the HTML5 History API’s datatitlepushState and replaceState)
  • Provide a forwards-compatible experience for HTML4 States to HTML5 States (so if a hash-fallbacked url is accessed by a HTML5 browser it is naturally transformed into its non-hashed url equivalent)

The project also has a commercial friendly BSD license.

xui.History

xui.History includes a history.js “Adapter” implementation for Ext JS, and wraps it in an Ext.define‘ed class to be Ext.Loader friendly. The class extends Observable so attaching listeners is just like any other Ext JS component.

API

The API for xui.History class is almost identical to the history.js API, except that instead of firing history events on the window object, events are fired by xui.History directly.

init()

Initialize the History class. Must be called before use. Can be called more than once.
Example:
xui.History.init();
var state = xui.History.getState();

pushState(data, title, url)

Adds a new History entry

  • data (Object) The data associated with this entry. Accessible as event.data on statechange event object.
  • title (String) The title for this entry
  • url (String) REQUIRED  - history.js will attempt to fix the URL to be compatible with the document URL. For IE8 and HTML5 browsers to play well together, I found this format works well: ‘?report=/shipping/overview’

Example:
xui.History.pushState({name: 'Jack', ninja: true}, 'Jack Slocum', '?user=1234');

replaceState(data, title, url)

Replace the current history state

  • data (Object) The data associated with this entry. Accessible as event.data on statechange event object.
  • title (String) The title for this entry
  • url (String) REQUIRED - history.js will attempt to fix the URL to be compatible with the document URL. For IE8 and HTML5 browsers to play well together, I found this format works well: ‘?report=/shipping/overview’

getState()

Return the current History state as an object with the following properties:

  • data (Object) The data associated with this entry.
  • title (String) The title for this entry
  • url (String)

back()

Go back one entry in the History (same as hitting the browser’s back button)

forward()

Go forward one entry in the History (same as hitting the browser’s forward button)

go(x)

Moves x entries in the History. Use a negative number to move backwards.

  • x (Number) The number of entries to move

Events

statechange

Fired when the state of the page changes. The event object contains the following properties:

  • data (Object) The data associated with this entry.
  • title (String) The title for this entry
  • url (String)

Example: xui.History.on('statechange', function(e){ console.log(e.data); });

Results

After the switch, there is a noticeable improvement in response time when navigating through reports in browsers that support onhashchange or HTML5. For older browsers, there was no difference.

Download

The source and minified (19 kb) versions are available on Github in the extjs-history repository.