HistMan is a script that let’s you manage browser history (back/forward buttons) and bookmarking in Ajax applications using Mootools. My aim is to deliver a small and efficient framework that’s easily ported to frameworks other than Mootools. At the time of writing the supported browsers are FF2, IE6+ and Opera9. I haven’t tested with Safari yet.

How does it work?

HistMan uses different techniques to trick the browser’s History Engine.

Firefox: The technique to make History Management work in Firefox is based on polling. When the location hash (the # in the url) is changed, the FF history engine adds a new entry in the window.history array. HistMan looks for a change in the hash and when there’s a change it executes a callback function of which the hash refers to. The interval for polling is set at 200 ms. This means that there’s a change there’s a delay of 200 ms before the callback function is called. Lowering the interval would decrease this delay but would increase the processor usage on the client-side.

IE6+/Opera9: When HistMan is loaded it creates an hidden iframe. To add a new history entry to the history engine, we change the iframe’s location.href to a url including a GET request. The GET request sets some javascript that’s attached to the onload event of the body of the page that’s loaded into the iframe. The javascript then executes the callback function and changes the hash of it’s parent. When the location.href is changed, a new history entry is added, so that makes the back and forward navigation buttons work.

Both: To enable bookmarking we have the location hash. When HistMan loads, it checks the hash. If the hash has a corresponding entry in the registry it executes the corresponding callback function.

I’m not sure yet if I like it the way it works now. The techniques explained above are very dirty. I don’t like browser sniffing, polling, and the fact HistMan needs a server side script to make it work in IE and Opera. One thing I do like about it is that it’s so damn small, the uncompressed HistMan file is 2.2 kb. The version compressed with packer is just 1.3kb.

How do I use HistMan?

Basically HistMan works like this: someone clicks on an element, the location hash changes and then a javascript callback function is executed with some argument you gave. The hash refers to a callback function, so that’s the way HistMan knows which callback function should be executed. Hmm, just look at the following example and you might understand the way HistMan works.

I tried to keep it as simple as possible. An element that needs to add an history entry must have an history attribute. An history attribute contains an object with some key:value pairs set. Here’s an example:

<a href="#" class="someotherclassname history" history="{hash:'content2',arg:'content/content2.html'}">Show me some!</a>
<a href="#" class="history" history="{hash:'content3',arg:'content/content3.html',callback:'customFunc'}">Click me pls!</a>

The history attribute has two required keys: ‘hash’ and ‘arg’. There’s a third key ‘callback’ which let’s you assign a custom callback function to this hash. Make sure the hashes are unique, otherwise HistMan’ll act very strange. In this example I used anchor tags, but you can use HistMan with any kind of element you like, as long as there’s an history attribute set.

Ok, so now our elements are ready to be used with HistMan. Let’s add some javascript:

//element to update
var content = $('contentBox');

//The default callback function, this one is called by the first anchor,
//because it didn't specify a custom callback in the history attribute.
function defaultCallback(url){
	new XHR({method:'get', onSuccess: function(response){
		content.setHTML(response);
	}}).send(url);
};

//The custom callback function, this one is called by the second anchor.
function customFunc(text){
	content.setHTML(text);
}

//Mootools has a window.ondomready event, other frameworks should add a function to the window.onload even.
window.addEvent('domready',function(){
	//location of the HistMan.php file
	var scriptUri = 'http://path/to/HistMan.php';
	//name of the default callback function
	var callback =  'defaultCallback';
	HistMan.start(scriptUri, callback);
});

I also have an online example so you can try it out. See it at the HistMan example page.

Programmatically adding history to an element

Since version 0.2 you can also add history to an element onclick event by using javascript. The syntax is very easy:

var element = $('histElement');
var histObj = {hash:'funnyElement',arg:'w00t!'};
HistMan.register(element, histObj); // => clicking on the element will add a history entry

Download

Get the latest version over here:

What do I need to use it?

Because HistMan uses a server side script you need a PHP server. I’m also working on a cgi script, because almost every webhost supports cgi. Also very important: HistMan is built on top of Mootools v1.0, so you need Mootools. I’m also working on a port to Prototype which should be ready soon. So stay tuned. If you still have questions, don’t hesitate to ask me. Just post a comment or contact me by email (b.wenneker+spamme@gmail.com).