setTimeout()和$(this)产生一个奇怪的bug

时间:2013-08-21 09:12:29

标签: jquery

我只是想用这个函数来模拟实时打字:

$('#expenseAccordion').on('keypress', '.netAmount input', function() {
    setTimeout(function() {
        $(this).closest('.accordion-group').find('.amount input').val($(this).val());
    }, 0);
});

这不起作用并产生这个奇怪的错误:

  

未捕获的TypeError:无法调用未定义的方法'toLowerCase'

存在问题的jQuery行(l 4245):

hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];

如果我从函数中删除所有$(this)并尝试这样的事情:

$('#expenseAccordion').on('keypress', '.netAmount input', function() {
setTimeout(function() {
    $('.amount input').val(4);
}, 0);

});

它可以工作,但我真的需要获取事件发生的当前元素,因为我有多个输入。

3 个答案:

答案 0 :(得分:10)

settimeout中的

this未指向expenseAccordion元素,您可以使用$.proxy()将自定义执行上下文传递给回调函数

setTimeout($.proxy(function() {
    $(this).closest('.accordion-group').find('.amount input').val($(this).val());
}, this), 0);

答案 1 :(得分:3)

另一种常见的方法是创建一个局部变量来保存它。

$('#expenseAccordion').on('keypress', '.netAmount input', function() {
    var $this = $(this);
    setTimeout(function() {
       $this.closest('.accordion-group').find('.amount input').val($this.val());
    }, 0);
 });

答案 2 :(得分:0)

第一个this指向您的超时,因此您所做的任何选择都将为空。

我将如何做到这一点:

$('#expenseAccordion').on('keypress', '.netAmount input', function() {
    var self = this;
    setTimeout(function() {
        $(self ).closest('.accordion-group').find('.amount input').val($(self).val());
    }, 0);
});