route.js - JavaScript Event Pooling on location.hash changes  

Thursday, October 22 2009

What is location.hash?

location.hash is a getter/setter for the location object of the Document Object Model

To put it simply, the value of location.hash will be whatever is after the # symbol in your browser’s url bar.

Event Pooling in jQuery

jQuery makes event pooling simple through the use of jQuery.bind() and jQuery.trigger().

In jQuery you can do the following:


jQuery(document).bind('#/websites', function(e) {
  alert('a');
});
jQuery(document).bind('#/websites', function(e) {
  alert('b');
});

/* Now two alerts have been bound to the name "#/websites" */
jQuery(document).trigger('#/website');//This will execute both alerts.

You can find a more detailed explanation of event pooling in jQuery @ http://www.michaelhamrah.com/blog/index.php/2008/12/event-pooling-with-jquery-using-bind-and-trigger-managing-complex-javascript/

Creating a cross-browser location.hash event dispatcher

We can create a simple dispatcher to trigger events to be executed when the browser’s location.hash changes.


var _hashchange_last = '';
var _onhashchange=function(){
  if(_hashchange_last!=location.hash){
    _hashchange_last=location.hash;
    jQuery(document).trigger(location.hash);
  }
}
setInterval(function () {_onhashchange();}, 50); /* poll for hashchange every 50 ms */

Now every time the location.hash of a browser is modified (via JavaScript or the browser’s url bar, or the browser’s back button) jQuery will attempt to trigger any methods which have been bound to that location.hash.

Notice there is a 50 ms poll checking for location.hash changes. In HTML5 we could use the browser’s new hashchange event, unfortunately there simply isn’t cross browser support for onhashchange so we are stuck with a 50ms interval.

Now jQuery is great and I love jQuery. I’ve told John Resig he’s my hero on multiple occasions. I just didn’t want the overhead of an entire JavaScript library when I could get away with using less then (1k) of code.

This is where route.js comes in!

route.js enables you to create “routes” based on a unique path a route can be considered a unique state a route may have multiple functions bound to them

ROUTE.JS USAGE


  route('#/account').bind(customMethod);
  route('#/account').bind(customMethod2);      

  route('#/websites').bind(customMethod);
  route('#/websites').bind(customMethod2);      

  route('#/account').run();
  route('#/websites').run();

  REGEX MATCHING:

  When calling route(path) you may specify a REGEX string for path

  WHERE THE ROUTES AT?

  All routes are stored globally in window['routes']
  console.log(window['routes']);

This is the good step towards building an advanced Javascript Application since we can now bind methods to unique location.hash’s.

Building on this concept Aaron Quint has created Sammy.js which is a jQuery implementation of Sinatra.

A great writeup on building applications around this concept can be found @ http://www.quirkey.com/blog/2009/09/15/sammy-js-couchdb-and-the-new-web-architecture/


  • Posted by Marak Squires