history.pushState -> location.hash -> query strings (no rewrites needed)
http://benalman.com/
by bizamajig
HTML
<script src="http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.js"></script>
<h1>history.pushState -> location.hash -> query string</h1>
<p>I know that using full paths is "all the rage" with pushState-enabled apps and demos, but by using query strings instead of full paths for both the default non-JavaScript links and enhanced pushState versions, the app can remain "single page" and not need any kind of server-side rewrites.</p>
<p>I've tested this in Chrome and FF4 (which support pushState) and FF2 (which doesn't), with JavaScript both enabled and disabled.</p>
<p>I need to spend more time with it, but this feels like a "best of both worlds" approach: it uses the latest technologies in a cool way, degrades well, and is very easy to implement.</p>
<h2>Sample application links:</h2>
<a href="?aaa" class="internal">aaa</a>
<a href="?bbb" class="internal">bbb</a>
<a href="?ccc" class="internal">ccc</a>
<h2>Log:</h2>
<div id="log"></div>
CSS
h1, h2 {
font-weight: 700;
}
h1, h2, p {
margin: 0.6em 0;
}
JavaScript
// unsure of the proper test for this
var supports_pushState = 'pushState' in history;
$('a.internal').on('click', function() {
alert( '1 - ' + this.search );
alert( '2 - ' + this.search.replace( /^\?/, '' ) );
var state = this.search.replace( /^\?/, '' );
if ( supports_pushState ) {
if ( state !== last_state ) {
history.pushState( {}, this.title || '', '?' + state );
handle( state, 'click' );
}
} else {
location.hash = '#' + state;
}
return false;
});
var last_state;
function handle( state, type ) {
if ( state !== last_state ) {
last_state = state;
// application code here
$('#log').append( 'state: ' + state + ' (' + type + ')<br>');
}
};
$(window)
.bind( 'popstate', function(e){
handle( location.search.replace( /^\?/, '' ), e.type );
})
.bind( 'hashchange', function(e){
handle( location.hash.replace( /^#/, '' ), e.type );
})
.trigger( supports_pushState ? 'popstate' : 'hashchange' );