If you want it to work in browsers that don't support history.pushState
and history.popState
yet, the "old" way is to set the fragment identifier, which won't cause a page reload.
The basic idea is to set the window.location.hash
property to a value that contains whatever state information you need, then either use the window.onhashchange event, or for older browsers that don't support onhashchange
(IE < 8, Firefox < 3.6), periodically check to see if the hash has changed (using setInterval
for example) and update the page. You will also need to check the hash value on page load to set up the initial content.
If you're using jQuery there's a hashchange plugin that will use whichever method the browser supports. I'm sure there are plugins for other libraries as well.
One thing to be careful of is colliding with ids on the page, because the browser will scroll to any element with a matching id.
Guys, I found that JQuery has only one effect: the page is reloaded when the back button is pressed. This has nothing to do with "ready".
How does this work? Well, JQuery adds an onunload event listener.
// http://code.jquery.com/jquery-latest.js
jQuery(window).bind("unload", function() { // ...
By default, it does nothing. But somehow this seems to trigger a reload in Safari, Opera and Mozilla -- no matter what the event handler contains.
[edit(Nickolay): here's why it works that way: webkit.org, developer.mozilla.org. Please read those articles (or my summary in a separate answer below) and consider whether you really need to do this and make your page load slower for your users.]
Can't believe it? Try this:
<body onunload=""><!-- This does the trick -->
<script type="text/javascript">
alert('first load / reload');
window.onload = function(){alert('onload')};
</script>
<a href="http://stackoverflow.com">click me, then press the back button</a>
</body>
You will see similar results when using JQuery.
You may want to compare to this one without onunload
<body><!-- Will not reload on back button -->
<script type="text/javascript">
alert('first load / reload');
window.onload = function(){alert('onload')};
</script>
<a href="http://stackoverflow.com">click me, then press the back button</a>
</body>
Best Answer
The only way to really do this (and is how the 'reallysimplehistory' does this), is by setting an interval that keeps checking the current hash, and comparing it against what it was before, we do this and let subscribers subscribe to a changed event that we fire if the hash changes.. its not perfect but browsers really don't support this event natively.
Update to keep this answer fresh:
If you are using jQuery (which today should be somewhat foundational for most) then a nice solution is to use the abstraction that jQuery gives you by using its events system to listen to hashchange events on the window object.
The nice thing here is you can write code that doesn't need to even worry about hashchange support, however you DO need to do some magic, in form of a somewhat lesser known jQuery feature jQuery special events.
With this feature you essentially get to run some setup code for any event, the first time somebody attempts to use the event in any way (such as binding to the event).
In this setup code you can check for native browser support and if the browser doesn't natively implement this, you can setup a single timer to poll for changes, and trigger the jQuery event.
This completely unbinds your code from needing to understand this support problem, the implementation of a special event of this kind is trivial (to get a simple 98% working version), but why do that when somebody else has already.