Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I pass the this context into an event handler?

I know this question doesn't make much sense, but let me try and clarify a bit.

I have a class, called ScrollBanner, and it looks somewhat as follows (a lot omitted for brevity):

function ScrollBanner() {     this.initialize = function(selector) {         $('span#banner1-nav').click(this._onClickNavigation);     }      this._onClickNavigation = function(event) {         this.restartTimer(); // this == span#banner1-nav element from this.initialize         //...     }      this.restartTimer() {         //...     } } 

As you can see this.initialize sets a click handler to this._onClickNavigation. Some might expect the this inside the event handler to refer to the ScrollBanner instance, but sadly it doesn't. It refers to the element that trigerred the click event, in this case span#banner1-nav

What would be the best way to get this to refer to the ScrollBanner class instance?

like image 312
josef.van.niekerk Avatar asked Mar 30 '11 18:03

josef.van.niekerk


People also ask

How do event handlers pass arguments?

If you want to pass a parameter to the click event handler you need to make use of the arrow function or bind the function. If you pass the argument directly the onClick function would be called automatically even before pressing the button.

How can you define event handler?

In programming, an event handler is a callback routine that operates asynchronously once an event takes place. It dictates the action that follows the event. The programmer writes a code for this action to take place. An event is an action that takes place when a user interacts with a program.

What method is the primary means of attaching a handler to an event?

The . bind() method is the primary means of attaching behavior to a document. All JavaScript event types, such as focus , mouseover , and resize , are allowed for eventType. Any string is legal for eventType ; if the string is not the name of a native JavaScript event, then the handler is bound to a custom event.


1 Answers

The old/traditional way:

Capture this in a variable:

this.initialize = function(selector) {     var that = this;     $('span#banner1-nav').click(function(event) {        that._onClickNavigation(event);     }); } 

You could also assign this to a variable e.g. instance:

function ScrollBanner() {     var instance = this;     // ... } 

and refer to instance instead of this in all the calls.

The overall idea is to store this in a variable in a higher scope.


The ECMAScript5 way:

ECMAScript5 introduces a new property of functions: .bind(). MDC's documentation shows an implementation for browsers that don't support it. With it you can bind a certain context to a function:

this.initialize = function(selector) {     $('span#banner1-nav').click(this._onClickNavigation.bind(this)); } 

but behind the scenes it is doing the same thing. The advantage is that you make use of built-in functionality in browser that support is.

Note that this is different from apply or call. Both of these set the context and execute the function, whereas bind only sets the context without executing the function.


The jQuery way:

jQuery provides a method $.proxy() that is doing the same:

$('span#banner1-nav').click($.proxy(this._onClickNavigation, this)); 
like image 85
Felix Kling Avatar answered Oct 15 '22 12:10

Felix Kling