setTimeout(function() { $('#selector').focus() }, 100);
,而不是
setTimeout($('#selector').focus, 100);
后者给了我在Firefox中一个TypeError this.trigger is not a function
,但显然它是一个功能,因为typeof $('#selector').focus
是“功能。”这里发生了什么?
setTimeout(function() { $('#selector').focus() }, 100);
,而不是
setTimeout($('#selector').focus, 100);
后者给了我在Firefox中一个TypeError this.trigger is not a function
,但显然它是一个功能,因为typeof $('#selector').focus
是“功能。”这里发生了什么?
这是因为this
问题。每MDN documentation:由setTimeout()
执行
代码从单独的执行上下文从中
setTimeout
被调用的函数调用。用于为被叫功能设置this
关键字的常用规则适用,如果您未在呼叫中设置this
或使用bind
,则它将默认为非严格模式下的全局(或window
)对象,或者严格为undefined
模式。它不会与调用setTimeout
的函数的这个值相同。
在JavaScript中,有一个“执行上下文”的概念,它是保存关于当前正在执行的内容的上下文的上下文。有一个全局执行上下文,当一个函数被调用时,会创建一个新的执行上下文。 this
值取决于执行上下文,并根据当前执行上下文进行设置。由于setTimeout
在调用目标函数时创建了新的执行上下文,因此this
不代表DOM中的jQuery对象,而是全局对象(因为它是默认的,或者在严格模式下未定义)。因此,当jQuery内部调用this.trigger
时,它试图调用不存在的window.trigger
。
尝试使用Function#bind
其中明确设置this
值:
setTimeout($('#selector').focus.bind($('#selector')), 100);
或者,瑞安提到:
setTimeout($.fn.focus.bind($('#selector')), 100);
当然,你可以,如斜视提到的,使用arrow function来代替,该比使用bind
和更惯用的更快:
setTimeout(() => $('#selector').focus(), 100);
可能会有帮助http://stackoverflow.com/questions/23640755/why-does-settimeout-require-anonymous-function-to-work –