views:

10030

answers:

11

I am using Ajax and hash for navigation. Is there a way to check if the window.location.hash changed like this?

http://example.com/blah#123 to http://example.com/blah#456

It works if i check it when the document loads. But If I have #hash based navigation it doesnt work when I press the back Button on the browser (so I jump from blah#456 to blah#123) It shows inside the address box but I can't catch it with JavaScript.

any Ideas? Thanks :)

+6  A: 

A decent implementation can be found at http://code.google.com/p/reallysimplehistory/ The only (but also) problem/bug it has is: in IE modifying location hash manually will reset the entire history stack (this is browser issue and it cannot be solved).

Note, IE8 does have support for "hashchange" event, and since it is becoming part of HTML5 you may expect other browsers to catch up.

Sergey Ilinsky
+12  A: 

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.

meandmycode
IE8 does. More to come
Sergey Ilinsky
The latest Firefox build (3.6 alpha) also now supports the native hash changed event: https://developer.mozilla.org/en/DOM/window.onhashchangeIt is certainly worth doing a check for this event, but note that IE8 will tell you the event exists when it is running in IE7 compat mode.. sadly the event doesn't fire.. you'll need to check for the event and that the browser doesn't appear to be IE7.. sigh (or attempt to trigger the event with IE's fireEvent method).
meandmycode
At the time of writing, WebKit also fires `hashchange` event, while Safari (stable) does not yet.
jholster
+2  A: 

Here's an implementation of meandmycode's suggestion.

Christoph
+4  A: 

As a side note, the current HTML5 draft specifies a hashchange event, which IE8 is the only browser to currently support.

Miles
+3  A: 

There are a lot of tricks to deal with History and window.location.hash in IE browsers:

  • As original question said, if you go from page a.html#b to a.html#c, and then hit the back button, the browser doesn't know that page has changed. Let me say it with an example: window.location.href will be 'a.html#c', no matter if you are in a.html#b or a.html#c.

  • Actually, a.html#b and a.html#c are stored in history only if elements '<a name="#b">' and '<a name="#c">' exists previously in the page.

  • However, if you put an iframe inside a page, navigate from a.html#b to a.html#c in that iframe and then hit the back button, iframe.contentWindow.document.location.href changes as expected.

  • If you use 'document.domain=something' in your code, then you can't access to iframe.contentWindow.document.open()' (and many History Managers does that)

I know this isn't a real response, but maybe IE-History notes are useful to somebody.

Sergio Cinos
A: 

I used a jquery plugin and wrote a YUI History like interface on top of it.

http://jstalkies.blogspot.com/2009/10/history-utility.html

Check it out once. If you need help I can help

moha297
+2  A: 

the firefox has an onhashchange event since 3.6

https://developer.mozilla.org/en/DOM/window.onhashchange

edfuh
+1  A: 

Another great implementation is jQuery History which will use the native onhashchange event if it is supported by the browser, if not it will use an iframe or interval appropriatly for the browser to ensure all the expected functionality is successfully emulated. It also provides a nice interface to bind to certain states.

Another project worth noting as well is jQuery Ajaxy which is pretty much an extension for jQuery History to add ajax to the mix. As when you start using ajax with hashes it get's quite complicated!

balupton
A: 

Ben Alman has a great jQuery plugin for dealing with this: http://benalman.com/projects/jquery-hashchange-plugin/

If you're not using jQuery it may be an interesting reference to dissect.

CJ
A: 

do any of these jquery history plugins work in ie9 ? using Ben Alman's implementation an error occurs when trying to refresh page .. surprinsingly .. hashChange event is triggered.

Another problem that I am having with ie9: I have a main window and a child iframe. Child iframes makes some ajax requests and on success calls window.parent.processResult (...).. Method is defined.. everything works perfectly fine in other browsers ie8, firefox, chrome. Of course I set document.domain='mydomain.com' in both parent and child window. Because of this document.domain set up some ajax requests that should happen in main window don't work anymore. any ideas ? If I remove the document.domain setting then my method can't be called.

Irina
Logically it should be working in IE9. hashChange even triggered since IE8 already. What the error msg? debug the error and modify the plugin a little bit.
CallMeLaNN
sorry..history works just fine... it seems that a javascript error occured because of setting document.domain='mydomain.com' and this was messing things.
Irina
A: 

you could easily implement an observer (the "watch" method) on the "hash" prop of "window.location" object. firefox has it's own implementation for watching changes of object ( https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/watch ) , but if you use some other implementation (such as http://stackoverflow.com/questions/1269633/javascript-watch-for-object-properties-changes ) - for other browsers, that will do the trick. the code will look like this :
window.location.watch( 'hash', function(id,oldVal,newVal){ console.log("the window's hash value has changed from "+oldval+" to "+newVal); } );
then you can test it :
var myHashLink = "home";
window.location = window.location + "#" + myHashLink;
and of course that will trigger your observer function.

gion_13