Reuse and Recycle: The History API

The new history API helps to solve one of the most troubling usability issues with Ajax application development (and Flash before it.) By default, if you use the back button on a single page app, you navigate away from the page in question. The expected behavior is to travel back to the previous state of the application.

This can mean potentially losing dozens or even hundreds of historical interactions.

While it’s true that there are script-based solutions available now to handle dynamic state in an Ajax application, the new HTML5 history API provides a single, standard solution. There’s no more choosing between schemes.

It’s not magical. In fact it leaves quite a bit of work to do. You still have to manage and reacreate application state, storing application data in a series of JavaScript objects that populate the history stack.

The following code sample illustrates a basic example. In this simple page a button click changes the color of the page background. Every time this button is pressed the history.pushState method is called. It accepts three arguments, an object representing the history state, a title for the state and a new URL to display in the browser.  The state is the most important argument. In this case it’s simply an object with one property color whose value is the new hex value of the page background. It should represent whatever info you need to recreate that state in the history stack.

To do that, you need to bind a function to the popostate event. This function process the same state passed into history.pushState. In this simple example it just reads the color property but it could do anything needed to rebuild application state. In this example we’re accessing the data in e.originalEvent because of the way that jQuery handles events. The abstraction/compatibility layer on top of the standard event handling buries the original event data one layer down. If you were binding events with window.addEventListener you could skip e = e.originalEvent.

<!doctype html>
<html>
<head>
  <meta  charset="utf-8">
  <title>History Example</title>
</head>
<body>
  <div id="main">
    <button  id="historymaker">click to add to the history stack</button>
    <p  id="reporter">The Background color is #ffffff</p> 
  </div>
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
  <script>
    $( document  ).ready(function(){
      $(  "#historymaker" ).on( "click" , function(){
        //http://paulirish.com/2009/random-hex-color-code-snippets
        var color  = '#'+Math.floor( Math.random()*16777215  ).toString( 16 ) ;
        $( "body"  ).css( { "background-color" : color } );
        $(  "#reporter" ).text( "The background color is " + color );
        history.pushState(  { "color" : color }, color, color.slice( 1 , color.length  )+".html" ); 
      })

      $( window ).on(  "popstate" , function( e ){
        e = e.originalEvent;
        if ( e.state !== null  ){
          $( "body"  ).css( { "background-color" : e.state.color } ); 
          $(  "#reporter" ).text( "The background color is " +  e.state.color);
        } else {
          $( "body"  ).css( { "background-color" : "#fff" } );
          $(  "#reporter" ).text( "The background color is #ffffff" );
        }
      });

   });
</script>
</body>
</html>

Leave a Reply

Your email address will not be published. Required fields are marked *