Object-Oriented Javascript borrow context for event handling
By: Jin Weijie
Tags: Contex, Event, JavaScript, Object Oriented

In object oriented Javascript programing, I used the following method to create “class”(in fact, there’s no class concept in Javascript):

var MyObj = function(){

}; MyObj.prototype={

aaa : function(){

}

,

bbb : function(){

}

,

ccc : function(){

}

}; Now I want to implement: Click an element in the page, call the aaa method in MyObj instance, then in aaa method, call ccc method. Attach event to the element in bbb method. So I can write like this: <div id="someA">Click Me</div>

<script>

var MyObj = function(){

}; MyObj.addEvent = function(oTarget, sEventType, fnHandler) {

if (oTarget.addEventListener) {

oTarget.addEventListener(sEventType, fnHandler, false);

} else if (oTarget.attachEvent) {

oTarget.attachEvent("on" + sEventType, fnHandler);

} else {

oTarget["on" + sEventType] = fnHandler;

}

}; MyObj.prototype={

aaa : function(event){

alert(event);

this.ccc();

}

,

bbb : function(){

MyObj.addEvent( document.getElementById("someA"), "click", this.aaa );

}

,

ccc : function(){

alert("in ccc;");

}

}; var o = new MyObj();

o.bbb(); </script> In aaa method, we get the event, but wait, this.ccc(); raises error: this.ccc is not a function What’s the problem? Because, when the click event fires on the element, the aaa method is executed but the context/scope is not in the instance of MyObj, in another word, this is the div element. The solution: call method of Function to borrow the context from the MyObj instance, so that the this.ccc() method is available in aaa method at execution time. First let’s see the definition of call method(from In this situation, we can use themethod ofto borrow the context from the MyObj instance, so that themethod is available inmethod at execution time. First let’s see the definition of call method(from http://www.javascriptkit.com/jsref/function.shtml ): Lets you call a function (funcA) as if it's a method of another function (funcB). Specifically, the " this " keyword when used inside funcA now returns funcB. The two methods apply() and call() are useful when you wish an object to "borrow" a method from another object and use it within its own context. Then we write a help method: MyObj.BindAsEventListener = function(object, fun) {

return function(event) {

return fun.call(object, (event || window.event));

}

}; At last, we modify the code to make it work: <div id="someA">Click Me</div>

<script>

var MyObj = function(){

//borrow the context from MyObj instance to _aaa method

//so that when _aaa is being executed, this keyword is combined to the instance of MyObj

this._aaa = MyObj.BindAsEventListener( this, this.aaa );

}; //add event helper method

MyObj.addEvent = function(oTarget, sEventType, fnHandler) {

if (oTarget.addEventListener) {

oTarget.addEventListener(sEventType, fnHandler, false);

} else if (oTarget.attachEvent) {

oTarget.attachEvent("on" + sEventType, fnHandler);

} else {

oTarget["on" + sEventType] = fnHandler;

}

}; //use call to borrow context

MyObj.BindAsEventListener = function(object, fun) {

return function(event) {

return fun.call(object, (event || window.event));

}

}; //the MyObj "class"

MyObj.prototype={

aaa : function(event){

alert(event);

this.ccc();

}

,

bbb : function(){

MyObj.addEvent( document.getElementById("someA"), "click", this._aaa );

}

,

ccc : function(){

alert("in ccc;");

}

}; var o = new MyObj();

o.bbb(); </script> Please refer the comments in the code, that’s it.