在事件处理程序中使用 this

Posted

技术标签:

【中文标题】在事件处理程序中使用 this【英文标题】:Using this inside an event handler 【发布时间】:2013-07-13 23:33:22 【问题描述】:

我试图在 DOM 3 级事件规范中的事件处理函数中查找 this 关键字的含义。

根据我的实验,this 指的是event.currentTarget 对象。

标准中的某处是否提到了这种行为?

根据“javascript The Definitive Guide”一书,this 指的是event target,这似乎是错误的。 event.currentTarget 似乎更符合逻辑,因为事件处理程序作为 html 元素对象的方法被调用。

有人可以澄清一下吗?

在冒泡的情况下,我看到“this”发生了变化,意味着 event.currentTarget.

【问题讨论】:

JavaScript "this" keyword的可能重复 man.. 你能在标记为重复的时候回答它吗? @Starx:不,不是。 我在这里找到了很好的解释,也谈到了事件处理程序。 digital-web.com/articles/scope_in_javascript @Bergi,他在问这个关键字代表什么,他会在那里读到很多答案。 【参考方案1】:

确实,在这种情况下,权威指南是错误的。

我在HTML5 event handler processing algorithm找到了一个参考:

使用一个参数调用callback,其值为Event对象E,回调此值设置为EcurrentTarget

DOM 级别 3 事件规范在以前的版本中并没有过多地说明它 - 它旨在与语言无关。刚才所说的Appendix F: ECMAScript Language Binding

事件监听函数: 这个函数没有返回值。参数应为实现Event接口的对象。

但是,当前版本省略了这些绑定。并在其词汇表附录中描述了event listeners:

事件处理程序事件监听器:实现EventListener接口并提供EventListener.handleEvent()回调方法的对象。事件处理程序是特定于语言的。事件处理程序特定对象(current event target)的上下文中调用,并由event 对象本身提供。

此外,即将发布的 DOM Level 4 草案,其goals 包含使 DOM 与 EcmaScript 的需求保持一致,并明确声明 in the Dispatching Events section:

如果listenercallback是一个Function对象,那么它的callback this value就是eventcurrentTarget属性值。

【讨论】:

请注意 HTML 5 规范 不是标准,DOM 规范是。 :-)。 DOM 规范是语言中立的(就像 4.01 之前的 HTML 规范一样),因此不包括像 this 关键字这样的语言特性。 @RobG 您的观点绝对有效。我对书的描述感到困惑,所以在这里问了这个问题。 @PK — 还应该提到,在许多地方,HTML5 只是记录行为(并在此过程中选择最喜欢的),所以虽然 Bergi 引用了 HTML5 规范。在大多数浏览器中,大多数情况下可能是正确的,但对于某些情况(例如,使用 IE 的 attachEvent 添加的侦听器)来说可能是正确的。 @RobG:感谢您的评论。我现在还在 DOM 3 级和 4 级规范中找到了参考资料 :-) @Bergi——为坚持不懈而赞叹。我不喜欢 DOM 标准变得更加以 ECMAScript 为中心,语言不可知论是他们的优点之一。侦听器在元素的“上下文”中被调用的语句推断该元素及其属性位于侦听器(函数的)作用域链(cf 执行上下文)上。将事件目标作为 this 传递应该是一种语言特性,已经有一个事件对象传递给具有对事件目标的引用的函数,因此无需设置 this (虽然它很方便)。没有this的语言怎么办?【参考方案2】:

在元素的事件处理程序中,默认捕获 (false),this 将引用检测到事件的元素。任一个都可以。

例如:

element.addEventListener('keydown', function (event) 
    // `this` will point to `element`
, false);

当捕获一个事件时 (true),比如在窗口级别,event.target 将引用发起该事件的元素,而 this 将引用捕获元素。例如:

window.addEventListener("error", function (event) 
    event.target.src = 'some_path';
    // `this` will point to window
    // `event.target` will point to the element that had an error
, true);

我希望这能说明两者之间的区别。

【讨论】:

以上是关于在事件处理程序中使用 this的主要内容,如果未能解决你的问题,请参考以下文章

从事件处理程序回调调用的函数中“this”的值?

在 jQuery 中使用 this 作为事件处理程序切换类

使用长度而不是事件处理程序通过 this 获取元素

Meteor 模板事件处理程序中“this”的上下文(使用 Handlebars 进行模板)

第十三章——事件(事件处理程序)

无法在事件处理程序中访问 React 实例(this)[重复]