jQuery:将 $(this) 传递给命名函数事件处理程序

Posted

技术标签:

【中文标题】jQuery:将 $(this) 传递给命名函数事件处理程序【英文标题】:jQuery: passing $(this) to named function event handler 【发布时间】:2012-02-19 23:16:47 【问题描述】:

我注意到建议use named functions when binding an event handler to a javascript event。当我的函数需要传递this 对象时,我该怎么做?

例如,我如何通过直接调用doFancyStuff来替换下面的匿名函数:

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

function doFancyStuff($textbox) 
    // fanciness

如果您指出我可能会违反上述代码的其他约定,请加分。


为了澄清,我想在我的示例中从多个地方调用doFancyStuff() 方法,否则是的,我可以这样做:

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

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

    // fanciness

【问题讨论】:

【参考方案1】:

我会说这是一个见仁见智的问题。我认为在这里使用匿名函数没有问题。如果这是唯一调用 doFancyStuff 的地方,您可以这样做:

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

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

但是,如果从多个位置调用此函数并且您无法更改其工作方式,则必须执行以下操作:

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

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


function doFancyStuff($textbox) 
    // fanciness

这很乱。

【讨论】:

不幸的是,该函数是从多个地方调用的——有些地方this 不是我希望该函数可以访问的$textbox。您对如何更改功能以更好地满足我的需要有什么建议吗? 第二个示例是解决此问题的方法,尽管我更喜欢您开始使用的具有匿名函数的代码。此外,您可能会使用第一个参数并检查第一个参数是 jquery 对象还是事件,并且在每个参数中的工作方式不同,我再次发现这比内联函数更混乱。 测试第一个参数以查看它是什么类型的示例:jsfiddle.net/Rzsep 但我没有把它放在我的答案中,因为我不喜欢它。请注意,我测试它是否是一个事件的方式可能是一种糟糕的测试方式,但它又快又脏。【参考方案2】:

我使用$.proxy来解决这个问题:

$(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

如果doFancyStuff是一个对象方法,那么能够给出myChoiceOfThis这样的引用是非常有用的。

【讨论】:

这是一个非常巧妙的方法。您可以在传递给代理的任何元素的上下文中执行事件处理程序。 var proxy = $.proxy(doFancyStuff, $('.my-other-element'));proxy(); 非常好的答案!最好和最简单的方法!【参考方案3】:

按原样传递函数:

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

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

jQuery 将使用适当的上下文集自动调用您的函数。


至于other conventions you might be breaking:你确定需要事件委托吗?如果没有,这会更好:

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

或者您甚至可以使用简写版本:

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

【讨论】:

在这种情况下我确实需要事件委托,但对于其他正在研究这个问题的人来说是个好主意【参考方案4】:

如果将 $(this) 定义为事件处理程序,您实际上可以在方法 doFancyStuff 中使用它。 .on() 方法将相应地设置上下文(this):

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

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

【讨论】:

【参考方案5】:

您必须更改 doFancyStuff 以期望与您的匿名函数相同的签名。按照您的编码方式,它看起来需要一个 jQuery 对象的单个参数,并忽略“this”。但是事件的参数是别的东西(事件对象),“this”是目标。如果您想将函数用作事件目标,那么它必须期待相同的数据。所以重写:

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

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

【讨论】:

以上是关于jQuery:将 $(this) 传递给命名函数事件处理程序的主要内容,如果未能解决你的问题,请参考以下文章

jquery 命名空间:如何将默认选项从一种方法传递给子序列方法?

使用 Django 和 Jquery 将选择选项值传递给命名的 url 模式

为命名函数启用 jQuery "$" 符号

jquery 方向传递给 animate()

OpenCart 将数组返回到 JSON 并传递给 jQuery

如何 curry jQuery 方法——哪个`this`值将传递 jQuery 对象?