luke
luke

Reputation: 3599

Pass function reference as event handler in jQuery

I am trying to pass function reference as event handler in jQuery. I would like to use a shorthand like in the simple example below...

$("a").click(console.debug.bind(undefined,this));

...rather than passing explicitly the whole function body:

 $("a").click(function() {
     console.debug(this)
 });

Moreover, I would like to access elements selected by jQuery in my shorthand function (and pass them as a parameter). In other words: I expect to have a result of $("a") as a this (or any other code that will retrieve the result).

So far I've tried:

var a = function() {
    console.debug(this);
};

var b = console.debug.bind(undefined,this); 

$("a").click(function() {console.debug(this)}); // prints link
$("a").click(a); // prints link 
b(); // prints Window
$("a").click(console.debug.bind(undefined,this)); // prints Window & jQuery.Event

Here is the fiddle: https://jsfiddle.net/hbqw2z93/1/

My questions are:

  1. Is it possible to use such construction and meet all requirements, without definition of additional variables - just one line as shown above?
  2. Is it possible to access jQuery's selection result using described approach?
  3. Why in the given scope this becomes 'merged' Window and jQuery.Event object?

Upvotes: 0

Views: 1051

Answers (2)

Denis Mysenko
Denis Mysenko

Reputation: 6534

  • You already using it, aren't you? :) It's limited, but it works in your own fiddle

  • jQuery will pass event object to your specified function. You can use function bind to pass that as an argument (you already have this working in your fiddle)

  • It doesn't. See what's happening:

jQuery passed one argument to click handler function - event object. You pass console.debug.bind(undefined, this) as a handler function so jQuery will call it with one argument.

Then, when you are binding you are asking to use 'undefined' as a 'this' object inside the function and sending an extra argument - 'this', which is a Window at this scope because you are binding at the highest level.

So when actual click happens, jQuery calls console.debug with two parameters - Window object that was bound during click() and jQuery event that is always passed to click handler. console.debug() can accept and display multiple objects, which is exactly what you see in the developer console.

Upvotes: 1

I wrestled a bear once.
I wrestled a bear once.

Reputation: 23379

The first parameter of bind is the new context to use for this. By passing undefined you are essentially not passing the first parameter.

The second and further parameters are passed into the function as the first values.

Note also that this when in the global scope, refers to the window object.

So here, b...

console.debug.bind(undefined,this);

is identical to...

function(){ console.debug(window); }

..since you're passing this (which is window) as the first parameter to debug.

By default, when you attach an event to the element, this will automatically point to the element which caught the event, so bind shouldn't even be necessary, which is why $("a").click(a); worked without using bind.

Upvotes: 1

Related Questions