Deeplinking with HTML5

October 11th, 2011

The original article has been retrieved from the internet archive machine and edited for fluidity.

Since I had different needs that the one given with swfaddress, I decided to write my own. Plus being a real challenge to learn while rewriting such a famous library, it’s a good opportunity to add the html5 window.history.pushState feature and get clean non hashed urls.

The current SWFAddress version listens to onhashchange events and operates fully on window.location.hash. For older browsers, there's a fallback strategy with a timer which checks at low intervals the current browser values against some cached values. If different, the url has changed and a function is called. That’s it.

Recently was introduced the HTML History API, with its pushState methods which has the ability to rewrite the current url without having to use a hash. So, prettier urls and better indexation.

Using pushState changes the way we check for current url. We must now use window.location.href which holds an absolute url value, rather than window.location.hash which stores a relative value. You somehow need to strip out the base url off the values to operate seemlessly between the two methods.

Solving that is easy. There are plenty of solutions but the one I liked the most is to add an HTML <base> tag in your document's <head>, which describes the base url of your site.

As for now a big amount of (dummy) users are still using older browsers, so i also implemented the regular hash engine with events and timers, and choose what method to use with window.history.pushState != undefined test. I really thought that compatibility wouldn’t be a problem but since internet explorer doesn’t store hash values in its history I had to come with a hack implying an iframe, thanks to stackoverflow.

So, it’s working both ways: with and without hash :)

I first wrote it as a jQuery plugin because it was easier for me. Even if I mainly do flash websites, I still load jQuery for handy bootstraping features. A while after, i adapted the script to have a pure javascript object. It’s less automatic but there’s no dependencies :)

In short, it can be embedded in jQuery.deeplinking or used without dependencies as a global Deeplinking javascript object.

The plugin is also able to hook on the top of swfobject directly (both jQuery and standalone). It will try to fire a single function called ‘deeplinking’ with the event type as first argument. Because jQuery’s swfobject plugin had a different behavior — including the object element in the selector instead of replacing it — i had to fork it and do some magic there :/ Bare with me friends.

The good news is that, you can even use it with flash content <3

Btw, if you’re using that jQuery plugin for a flash projet, you may be interested in fixing an annoying resizing bug generated by jQuery itself.

Documentation

You can access the static deeplinking object by using deeplinking for the standalone version, and $.deeplinking for the jQuery version. After that it's all the same.

Functions worth mentioning:

deeplinking.onready: Set a function and it will be called when the deeplinking object is ready and running.

deeplinking.oninternalchange: Set a function and it'll be called when there's an internal url update (basically, when you set the deeplinking value by the code).

deeplinking.onexternalchange: Set a function and it'll be called when there's an external url update. It’s the most useful: it’ll be fired when the user changes the url, or press back/forward buttons.

deeplinking.value(): It’s a getter/setter function (depending if there's an argument or not). It will either return the current url, or set the url with the provided value and fire the oninternalchange callback.

deeplinking.initialize(): You need to call this method, hopefully on dom ready. When used with flash, I found that I was easier to let Flash call this method with an ExternalInterface.call(). With jQuery, it’s automatically fired on domready, so chill out.

deeplinking.activate(): Enables the url watcher

deeplinking.deactivate(): Disables the url watcher

deeplinking.log: a log function, for debugging purpose. logging is deactivated by default, but you can turn it on with debug

deeplinking.debug: flip this boolean to true to activate logging

deeplinking.html5: flip this boolean to force the use of pushState, but also force the use of hash (if false)

Compatibility

It's been manually tested on:

Mozilla Firefox 6 and 7, Chrome 14, Internet Explorer 6/7/8 and Safari 4 for Windows for the PC part, and Mozilla Firefox 7, Chrome 14, Safari 4 for the MacOS part.

Fourchette it on github :)