I’m currently writing a class for a game I’m working on that controls application routing based on hash changes in the page URL.
My problem is that the context of “this” changes to “window” after attaching the main routing function to the hashchange event.
Here is the code so far:
Game.Router = function() {
return {
init: function() {
window.addEventListener('hashchange', this.route, false);
},
route: function(e) {
e.preventDefault();
var routingLocation = e.newURL.substr(e.newURL.indexOf('#!/') + 3, e.newURL.length);
switch(routingLocation) {
case "new":
this.toggleView('Game');
break;
case "instructions":
this.toggleView('Instructions');
break;
case "scores":
this.toggleView('Scores');
break;
case "about":
this.toggleView('About');
break;
}
},
toggleView: function(viewID) {
var els = document.querySelectorAll('section');
for(var i=0, l=els.length; i<l; i++) {
if(els[i].id == viewID) {
els[i].className = 'currentGameSection';
} else {
els[i].className = '';
}
}
}
}
}();
When I try and call this.toggleView in the route function’s switch statement, it turns out that “this” has changed from Game.Router to window. The problem can be fixed by replacing this.toggleView with Game.Router.toggleView, but this isn’t ideal.
Could someone please help me understand why the “this” context changes after adding the event listener?
I hope the link I gave makes the reason of your problem clear.
In order not to give the usual closure solution, here’s a simpler one (not compatible with IE8-) :