Experiments with HTML5 history

Let’s try playing with HTML5 history starting with something simple:

 <!DOCTYPE html>
 <html>
 	<head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
 		<script src="jquery-1.4.4.js" type="text/javascript" charset="utf-8"></script>
 	</head>
 	<body>
 		<a href="page1.html">Page 1</a>
 		<a href="page2.html">Page 2</a>
 		<a href="page3.html">Page 3</a>
 		<div id="content"></div>
 	</body>
 </html>

Nothing incredible so far. Now let’s have the links to load the content in the div:

 <!DOCTYPE html>
 <html>
 	<head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
 		<script src="jquery-1.4.4.js" type="text/javascript" charset="utf-8"></script>
 		<script type="text/javascript" charset="utf-8">
 			$(function() {
 				$('a').click(function(){
 					$.get(this.href, function(data){
 						$("#content").html(data);
 					});
 					return false;
 				});
 			});
 		</script>
 	</head>
 	<body>
 		<a href="page1.html">Page 1</a>
 		<a href="page2.html">Page 2</a>
 		<a href="page3.html">Page 3</a>
 		<div id="content"></div>
 	</body>
 </html>

Now the requests are made with AJAX and the browser history is not updated, thus the browser back button will not work as expected. Let’s first update the browser address bar:

 $('a').click(function(){
	history.pushState({page: this.href}, '', this.href);
	$.get(this.href, function(data){
		$("#content").html(data);
	});
	return false;
});

Note the history.pushState(stateObj, title, url) method. It has 3 parameters:

The back button doesn’t work yet. Let’s take care of that:

$(function() {
	var homeUrl = location.pathname;
	$('a.ajax').click(function(){
		history.pushState({}, '', this.href);
		$.get(this.href, function(data){
			$("#content").html(data);
		});
		return false;
	});
	$(window).bind('popstate', function(e){
		var url = location.pathname;
		console.log("Back to: " + url);
		// let's prevent the page to include itself
		if(homeUrl != url) {
			$.get(url, function(data){
				$("#content").html(data);
			});
		}
	});
});

I’ve not been able to fetch back the data parameter of the pushState method. I would have liked to store the requested URL there. Any clue?

Shorter version

If we’re using Rails RJS files there’s a simple way to use all this:

$(function(){
  // clicking on links
  $("a").live('click', function() {
    $.getScript(this.href);
    history.pushState(null, '', this.href);
    return false;
  });
  // hitting the back button
  $(window).bind("popstate", function(){
    $.getScript(location.href);
  });
});

Sources