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 模式