【问题标题】:jQuery: passing $(this) to named function event handlerjQuery:将 $(this) 传递给命名函数事件处理程序
【发布时间】: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
}

【问题讨论】:

    标签: javascript jquery coding-style


    【解决方案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
      } 
      

      【讨论】:

        猜你喜欢
        • 2016-06-23
        • 2011-07-26
        • 1970-01-01
        • 1970-01-01
        • 2012-08-30
        • 2011-12-07
        • 1970-01-01
        相关资源
        最近更新 更多