I have the following code
console.info('checking if url contains hash');
if (!location.hash) {
console.warn('if-block replacing hash to empty!');
location.href = '#';
// Running route() to trigger Router.otherwise()
console.info('running route() from if-block(hash doesn\'t exist)');
route(location.hash.slice(1));
} else {
// URL contains a hash. Running Router.when() to load template
console.info('running route() from else-block(hash already present in url)');
route(location.hash.slice(1));
}
// Bind hashchange-event to window-object... duh
console.info('binding hashchange event');
$(window).on('hashchange', function () {
console.info('running route() from hashchange');
route(location.hash.slice(1));
});
Clearly, the event listener is attached after the else-if block. My console's output verifies this
2015-02-13 12:51:14.281 main.js:69 checking if url contains hash
2015-02-13 12:51:14.284 main.js:71 if-block replacing hash to empty!
2015-02-13 12:51:14.290 main.js:75 running route() from if-block(hash doesn\'t exist)
2015-02-13 12:51:16.677 main.js:84 binding hashchange event
2015-02-13 12:51:16.678 main.js:86 running route() from hashchange
It looks like the event listener somehow picks up the previously triggered hashchange event.
This only occurs when the url is example.com
, not example.com/#
. If /
or /#
is missing from the url when you enter the site this phenomenon triggers.
Edit: The problem I'm experiencing is that the hashchange
event listener is triggering before it's even listening to hash changes. I'm wondering if that's normal.
Another edit:
An even clearer example showing that when I first run getEventListeners(window)
, no listeners are attached to the hashchange
event. Despite that, when I do add the event listener, it picks up a previously triggered hashchange
Am I missing something here or what's going on?
Is there any way to bypass this?
Let's simplify your code to
location.hash = 'foobar';
window.onhashchange = function() {
document.body.innerHTML = 'You should not see me. But you do :(';
};
To fix the problem, you can use setTimeout
to delay the addition of the event handler:
location.hash = 'foobar';
setTimeout(function(){ // Delayed code
window.onhashchange = function() {
document.body.innerHTML = 'You should not see me. And you do not :)';
};
}, 0);