简体   繁体   中英

jQuery: passing $(this) to named function event handler

I note that it's recommended to use named functions when binding an event handler to a javascript event . How can I do this when my function needs to be passed the this object?

For example, how would I replace the anonymous function below by directly calling doFancyStuff :

$(document).on('change', 'input.fancy-textbox', function () {
    doFancyStuff($(this));
});

function doFancyStuff($textbox) {
    // fanciness
}

Extra points if you point out other conventions I might be breaking with the above code.


To clarify, I want to call the doFancyStuff() method in my example from multiple places, otherwise yes, I could just do something like this:

$(document).on('change', 'input.fancy-textbox', doFancyStuff);

function doFancyStuff() {
    var $textbox = $(this);

    // fanciness
}

I would say that's a matter of opinion. I see no problem using an anonymous function here. If this is the only place doFancyStuff is called, you could do this:

$(document).on('change', 'input.fancy-textbox', doFancyStuff);

function doFancyStuff() {
    // fanciness
    var $textbox = $(this)
}

However, if this function is called from multiple places and you can't change the way it works, you would have to do something like this:

$(document).on('change', 'input.fancy-textbox', doFancyStuffFromEvent);

function doFancyStuffFromEvent() {
    // fanciness
    doFancyStuff($(this));
}

function doFancyStuff($textbox) {
    // fanciness
}

Which is messy.

I use $.proxy to solve this issue:

$(document).on('change', 'input.fancy-textbox', $.proxy(doFancyStuff, myChoiceofThis);

function doFancyStuff(event) {

    // $el is the same as $(this) when using anonymous functions
    var $el = $(event.currentTarget); 

    // me === myChoiceOfThis 
    var me = this; // me === myChoiceOfThis
}

If doFancyStuff is an object method, then being able to give a reference such as myChoiceOfThis is very useful.

Just pass the function as is:

$(document).on('change', 'input.fancy-textbox', doFancyStuff);

function doFancyStuff() {
    $(this).fancy(); // :-P
}

jQuery will automatically invoke your function with the proper context set.


As for other conventions you might be breaking : are you sure you need event delegation? If not, this would be much better:

$('input.fancy-textbox').on('change', doFancyStuff);

or you could even use the short-hand version:

$('input.fancy-textbox').change(doFancyStuff);

You will actually be able to use $(this) inside your method doFancyStuff if you define it as your event handler. The .on() method will set the context (this) accordingly:

$(document).on('change', 'input.fancy-textbox', doFancyStuff);

function doFancyStuff() {
    // 'this' will be the changed input.fancy-textbox
}

You have to change doFancyStuff to expect the same signature as your anonymous function. The way you've coded this, it looks like it expects a single parameter of a jQuery object, and ignores "this." But the parameter of an event is something else (the event object) and "this" is the target. If you want to use a function as an event target, then it's got to expect the same data. So rewrite:

$(document).on('change', 'input.fancy-textbox', doFancyStuff);

function doFancyStuff(e) {
    var $textbox = $(this);       
    // fanciness
} 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM