views:

82

answers:

1

So I'd like my page to load content if a window's hash has changed.

Using Mootools, this is pretty easy:

$extend(Element.NativeEvents, {
    hashchange: 1
});

and then:

window.addEvent('hashchange', function() {});

However, the hashchange event is firing when the page is being loaded, even though the specification require it not to fire until the page load is complete!

Unless I am loading the page for the first time, with no hash, then all works as expected.

I think the problem here is the fact that the browser considers the page load "complete", and then runs the rest of the JavaScript, which includes hash detection to load the requisite page.

For example, if I typed in http://foo.bar/, all would work fine. However, http://foo.bar/#test would, ideally, load the initial page, detect the hash, and load the "test" content.

Unfortunately, the browser loads the initial page, considers it "domready", and THEN loads the "test" content, which would then fire onHashChange. Oops?

This causes an infinite loop, unless I specifically ask the browser NOT to update the hash if an onHashChange event is firing. That's easy:

var noHashChange;
noHashChange = true;
var hashes = window.location.hash.substr(1).split("/"); // Deciphers the hash, in this case, hashes[0] is "test"
selectContent(hashes[0]); // Here, selectContent would read noHashChange, and wouldn't update the hash
noHashChange = false;

So now, updating the hash AFTER the page has loaded will work properly. Except it still goes nuts on an initial page load and fetches the content about 3 or 4 times, because it keeps detecting the hash has changed. Messy.

I think it may have something to do with how I am setting the hash, but I can't think of a better way to do so except:

window.location.hash = foobar;

... inside of a function that is run whenever new content is selected.

Therein lies the problem, yes? The page is loaded, THEN the content is loaded (if there is content)...

I hope I've been coherent...

A: 

Perhaps you could check the hash first to eliminate the recursion:

 if(window.location.hash != foobar){ window.location.hash = foobar;}

Why is the onHashChange handler changing the hash anyways? If there's some default that it's selecting first before loading the content, then perhaps that could go in a seperate function.

(I say this because it looks like you've some sort of directory structure-esque convention to your location.hash'es, perhaps you're selecting a specific leaf of a tree when the root is selected or something?)

Tim Snowhite
As it turns out, I haven't been coherent much, since, reading over my question, I have no idea what I was trying to say.Cheers on the answer, it is indeed a directory structure. I'll check out your solution.
Julian H. Lam
Can you post your correct solution or select an answer as the correct one for this question?
Tim Snowhite