I'm noticing that this
references something else inside a function that I added as event listener. I read this informative resource and a few questions on stackoverflow but I don't know how to apply it to my case (I'm quite new to the "oop" and the module pattern in javascript so I'm a bit lost).
Here is my little module:
var myModule = myModule || ( function() {
// Adds event listener for all browsers
// see http://stackoverflow.com/a/6348597
function addEvent( element, event, listener ) {
// IE < 9 has only attachElement
// IE >= 9 has addEventListener
if ( element.addEventListener ) {
return element.addEventListener( event, listener, false );
} else if ( element.attachElement ) {
return element.attachElement( "on" + event, listener );
}
}
return {
init: function() {
// Add event listeners
addEvent(
document.getElementById( "myElementId" ),
"click",
this.processMyElement
);
addEvent(
document.getElementById( "myOtherElementId" ),
"click",
this.processMyOtherElement
);
},
hideElementById: function( elementId ) {
document.getElementById( elementId ).style.display = "none";
},
showElementById: function( elementId ) {
document.getElementById( elementId ).style.display = "block";
},
processMyElement: function() {
this.hideElementById( "myElementId" );
this.showElementById( "myOtherElementId" );
},
processMyOtherElement: function() {
// Do something else...
}
};
}() );
The thing is that this
which I use to call hideElementById
in processMyElement
is referencing to the element I added an eventListener to, and not to the current object.
I tried a few things without success:
return
in addEvent
,var that = this
as a private property of the module (placed in the module before the addEvent
definition) and using that
in processMyElement
apply
in the init
method but it (obviously) calls processMyElement
when adding the listener to the elementCould anyone help me with this? I tried a few things but I cannot see how to do it better...
PS: I try to build testable code, that's why I had those hideElementById
and showElementById
methods, in order to separate various functionalities (that may be quite clumsy actually but that's where I am ATM...).
There are (more than) a couple of common ways to get the correct this
binding. For example, you can use a closure:
var that = this;
addEvent(
document.getElementById( "myOtherElementId" ),
"click",
function () {
that.processMyOtherElement();
}
);
Or you could use bind:
addEvent(
document.getElementById( "myOtherElementId" ),
"click",
this.processMyOtherElement.bind(this)
);
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind
The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
Which one you use would depend on other factors.