Who am I?
Who are you?
Developers and user experience folks who ...
want to meet user expectations.
want to understand the Ajax/back button problem.
aren't afraid of a little code.
How we'll spend the next 90 minutes
A brief history of Ajax history management
Current approaches to Ajax history
Lessons from Really Simple History
The future of Ajax history management
1. A brief history of Ajax history management
(the infamous broken back button)
Breaking your back buttons is like saying, "don't click this button more than once."
You're asking users to change 15 years of ingrained expectations.
Remember the infinite meta-refresh loop? It's like that, too.
(bookmarks that go nowhere)
Breaking bookmarks is like saying, "get lost ... literally."
You're 86ing your SEO and letting users know they can't rely on your site.
So who needs Ajax history management, anyway?
You looking at me?
Ajax history management: A problem older than Ajax itself
This partial loss of browser History is not optimal, but it is offset by PPR's benefits. PPR not only improves application performance, but it also improves user experience of the application -- unlike full page reloads, PPR does not does not "flash" and force the user to the top of the page, and thus provides a minimum of distraction from the task at hand.
- PPR (Partial Page Rendering), Oracle, 2003
Q: How did we break the history stack and bookmark mechanism so badly?
A: New technologies, plus a lack of standards.
About the "standard" history stack
HTML 4.01 : No explicit history spec.
DOM Level 0 provides a window.history object.
The window.history interface defines only bare-bones properties and methods
back, forward and go methods
length property
Browser vendors all follow the same model for GUI access... mostly.
back and forward buttons
history menu
How Ajax breaks window.history
If the URL doesn't change, then no history entry gets created.
If the URL doesn't include information about an Ajax application's state, then the application can't recreate that state.
Q: So how do we fix it?
A: For now, we hack
Ajax history managers work by manipulating browser quirks to create new entries in the history stack.
Tricking the browser
HTML 4.01 provides the fragment identifier, a.k.a the hash.
In some browsers, changes to the current URL's fragment identifier create a history entry without hitting the server.
In other browsers, navigation within an iframe creates history entries even if the parent document's URL doesn't change.
In most browsers, unsubmitted forms retain their values across the current session.
Steps in the history management process
Trick the browser into creating a new entry in the history stack using the hash or an iframe.
Stash data in that history entry in the hash token or in the iframe title.
Create a timer function that waits for the hash/iframe to change as the result of user action.
Trigger a callback that grabs your stashed data from the hash/iframe and passes it back to your application.
Let your Ajax application do the rest.
Sounds simple!
So why is Ajax history management so complicated?
IE6/7
iframe manipulation
Gecko
hash changes
Opera 9
broken timers
Safari 2
broken history.length
Safari 3.0/Win
just broken
IE8
onhashchange
Chrome
broken form fields
2. Current approaches to Ajax history management
Many major webapps now employ custom history management systems
Popular libraries also have their own history systems
They're all solid, but we're going to look at single-purpose libraries instead.
Why choose a particular history manager?
As with general-purpose JavaScript frameworks, it's all a matter of API
The right tool for the right team, the right technology & the right project
Really Simple History Overview
Brad Neuberg of Dojo (and now Google) created it.
I currently maintain it.
I'm looking to share that responsbility.
More on that later.
Really Simple History Features
Isn't tied to any specific low-level Ajax framework.
Uses hidden form fields to retain data across a session
Lets you take detours and still retain history.
Stores state as key/value pairs.
Keys live in the browser hash or an iframe.
Values are JSON data stashed in a hidden form field.
Keys last across sessions; values last only within a session.
Really Simple History Timeline
Version 0.4
2005
Brad's last version
supported IE6, FF1.5
Version 0.6
2007
my first version
supports IE7, Safari 2, Opera 9
Version 0.8
2008
in progress
more on that later
RSH API
Two objects: dhtmlHistory and historyStorage
dhtmlHistory has most of the public methods
create uses document.write to create its inner workings
init grabs the initial state and sets things up
addListener binds history changes to a callback function
add creates a new entry in the history stack
Show and tell (just view source)
Developed by Andrew Mattie
Uses iframes even in non-IE browsers so history points don't require hash changes
Hash changes for bookmarks
Binds functions rather than data to each history point
No Safari 2 or Opera support
Show and tell
Developed by Nathan Hammond
Very new
Rewrite and optimization of Really Simple History
Tied to jQuery ... for now
Supports most common use cases only ... for now
Adds some new form-related functionality
Show and tell
3. What I learned from Really Simple History
Lessons from RSH 0.6
Don't couple tightly to current browser limitations
Avoid the big-ball-of-wax approach
Try to be future-proof
Cover the common cases
Leave the bells and whistles for plugins
Build hooks for community participation
Goals for RSH 0.8
Support Chrome, IE8, Safari 3, Opera 9.5
Provide defensive browser-sniffing; assume less
Isolate each UA-specific implementation
Move secondary features, such as storage, to plugins
Provide plenty of callback hooks
Borrow optimizations from other libraries
Make collaboration easier
Show and tell
Goals for RSH 1.0
Circle back with JSSM
Share code stewardship with Nathan Hammond
Pull UA-specific code dynamically
Provide full unit testing suite
Write thorough documentation
Enable customizable builds
Foster an add-on ecosystem
Build full-on, real-world example apps
4. The future of Ajax history management
Alternate approaches
Zach Leatherman's CSS-only breakthrough
Additional pain points
The document title problem
IE6/7 problems: multiple iframes; manual URL changes; peekaboo history entries; same domain issue
The TinyMCE problem
Code brittleness
The good news:
IE8 supports onhashchanged
No more iframes!
No more timers!
Yay ... right?
The bad news:
Still no history.pushState
Still no history.clearState
No way to handle titles gracefully (demo )
Q: How long will there still be a need for history management libraries?
A: It all depends on HTML 5's final specification and adoption speed
In other words, for a very long time.