History Keeper – Deep Linking in Flash & JavaScript

unFocus History Keeper – a JavaScript tool for managing browser history (back button) and deep linking in Flash and Ajax applications, enabling SEO.

You can check out an example page in SVN or check out adcSTUDO or Terminal Design’s fonts catalog for a demo. The test page contains a small JavaScript application that takes what you put in a text box, and makes a history entry out of it – a deep link will display that history entry in the body of the page as well.

You can also check out the latest version from SVN from either the trunk (I try to keep it working there, but no guarantees) or one of the tagged releases (each release gets a tag) if you want to be cutting edge.

Features:

Enables back button support, for your client-side web apps!

Hash based deep linking (Anchor Style – index.html#/foo/bar)

Event driven – Event Dispatcher

Support for all current browsers:

Opera

Firefox

Safari 1.2+

IE 5.5+

Google Chrome

Known Limitations: (I have to confirm if many of these are still a problem)

All history entries (back button states) modify the location string.

Doesn’t remember last entry if you leave the app and come back in some browsers (that’s a bug, I’ll fix it).

Editing the url manually will stop further updates to the url in some browsers.

Konqueror support is still a bit flaky (this history is off by one in an odd way).

Deep linking and back button functionality relies on ExternalInterface – so “allowScriptAccess” has to be set and working (platform defendant) for History Keeper to work (though you can actually get deep linking to work using flashvars, in a pinch).

Make sure whatever embed solution you are using, you have set the “id” attribute on your object or embed tag.

Related Links – Note: I’m trying to put links to everyone who helped me out over the years. If I left you out, please let me know.

There are a number of ways to do that. I used to have something in the unFocus tool set that would allow for that, but have discontinued it, since there is a built in (and more reliable) way to do that since Flash Player 8.

It’s called External Interface, and is fairly easy to use, once you wrap your head around it.

To send info into the swf from javascript, you’ll need to use ExternalInterface.addCallback to add a javascript function handle, then call that from Javascript by getting a reference to the embedded swf’s DOM object, and calling that method. Here is an example: unFocus.SwfUtilities.getSwfReference(“swfID”).yourCallbackFunction();

You’ll need to make sure you set Allowscriptaccess to a value that allows that communication with the script.

It’s possible I am blind…. But have tried finding instructions on this site in regard to implementing History Keeper, with no luck. I am new to flash and AS3, the examples provided in the download folder are not self-explanatory to myself… Advice/Insight/Direct me to further information? Would be much appreciated…

In IE8 hash (params after “?” symbol) presented like in any normal browser. But in IE < 8 this problem anyway exist.
Sorry for my English 🙂
(Note: This got caught up in Akismet for some reason. Sorry about that. I wonder what else gets lost in there.)

If you set document.domain then IE gives ‘Access is denied’ when trying to read (but, bizarrely, not change) window.location.

The reason we set document.domain is so that the main document on example.com can communicate with a child iframe on ajax.example.com. Both the main and child iframe documents need document.domain explicitly set to ‘example.com’, even if the main document is at http://example.com already (i.e. although the domain is example.com, it still needs to be explicitly set).

To clarify, the problem can be recreated just be running these two lines of JSript on a page:
document.domain = ‘yourdomainhere’;
alert(window.location); // will throw an access denied error in IE

If I leave the current page (say Page1.aspx, that implemented the history Keeper), and go to Page2.aspx.
Now if I try hitting the history back button and come back to Page1.aspx. I could see that the history is lost!
Is there any fix for this? Thanks in advance.

Hi Sreejith. I’m not sure what is causing that. I don’t remember this being a problem, but I was able to reproduce this easily enough. I have some work to do it looks like. Thanks for the bug report. Opera is a PIA, but I’ll look into that too.

About that bug – This seems to only apply to IE6 and 7, and it’s a bug in general with keeping a history using iframes, which affects other history scripts as well. I’ll keep looking for a fix, but it does look like Microsoft cleaned it up in IE8 (in IE8 mode), along with a bunch of other issues (like the title getting all screwed up).

I have noticed that most RIAs that use flash and history/deep linking techniques are making external links open in a new window. Maybe it’s partly to deal with this.

About that IE bug with “?” after the hash “#” – this appears to be a bug in IE that can’t be worked around. I’ll keep an eye out for a fix, but I think the answer will be that you simply can’t put a ? in the string after the hash, and maintain compatibility with IE < 8. Sorry about that. If you know of anyone that's done it, please let me know. 🙂

Can this track the history of multiple iframes too? When you click on something in an iframe it is added to the history but when you look at the history array you can’t se the iframe url, only the main page url. Why is that? When you press back the iframe goes back, how did it know to what url to go back to?

I haven’t looked at the history array in a while, but I suspect you are running up against the limits of what the browser can keep track of. Theoretically, all the browsers should be able to do what you are saying without error – but I bet reality is different. Most of the issues around that center on security issues – parent pages being able to access information about the content in an iframe – even the location – could be a security problem. So most of the browsers have erred on the side of caution and made it difficult or impossible to get that information across frames. Unfortunately, History Keeper really doesn’t deal with iframes too much, except to use a hidden iframe for IE5.5 – 7 compatibility, so I doubt it’ll be of any help.

Awesome utility, seems to work 99% of the time in all the major browsers according to my tests. The biggest flaw is that on some browsers users have to hit the back button twice. Though, overall highly recommended and suitable for use on high-traffic sites. Please, keep this code independent of any JavaScript library, as that is the best feature of all.

Thanks for the kind words. If you have any specific information on when the user must press the back button twice (browser/version/platform/etc.), I’d love to squash that bug.

A core design goal of HistoryKeeper is to keep it light, and dependent free (for easier and more flexible deployment). I’ll never add dependency on a third party library like jQuery, though I may eventually wrap a plugin around it to make things a bit easier for those who wish to integrate with jQuery.

any progress on some type of tutorial on implementing History Keeper? or do you know of anyone else who has compiled some type of guide/tutorial? i really like what ive seen so far with it and would be very interested in implementing it in my own flash website, but im still pretty much a beginner with flash and js, but experience with html.

Great work; thanks for sharing it with us. I am curious: have you tried using this inside an iframe? I’m having an issue with IE (what else is new?) whereby when you click the back button the iframe’s location will replace the parent’s location.

I vaguely remember something about a problem with using this inside of an iframe. I’d bet it simply will not work (hk creates it’s own iframe via javascript behind the scenes – stuff like that tends to make IE freak out). I’ll see if I can find some time to mess with it – but it seems I never do. 🙁

Thanks for replying. Yes, I’ve been looking at History.js & see what it’s doing. And when I get the time I’ll try running against the unpacked scripts & see what I can come up with as well; maybe we’ll get lucky 😉

I’ve tried it both ways – it’s more consistent if dispatches immediately Just make sure you store your current value locally, and check it in your listener. There are browser quirks that’ll cause this to fire at any rate, so it’s important to check the incoming value against your current state. You should probably also be filtering the URL data, to make sure it’s the same when it does come back from the browser (each of which encode special characters differently – ugh). At this point, I’ve actually been recommending alternative frameworks to history keeper, I just haven’t been on top of maintaining it, and there are some vital tools missing from the stack (like a URL filtering/cleaning tool, and some kind of state manager). Have a look at jQuery BBQ as a good alternative.