为什么我的 event.currentTarget 会自动更改?

App*_*rew 6 javascript jquery event-handling jquery-mobile

请看下面的代码。

function deferredClick(f) {
    return (function (e) {
        var $this = $(e.currentTarget);
        console.log('Actual target: ', e.currentTarget);

        window.setTimeout(function () {
            console.log('Target I get here: ', e.currentTarget);
            f.call($this.get(0), e);
        }, 1000);
    });
}

function clickResponder(e) {
    var $this = $(e.currentTarget);
    $("#out").html('Clicked - ' + $this.val());
}

$('input[type="button"]').on('vclick', deferredClick(clickResponder));
Run Code Online (Sandbox Code Playgroud)

这个想法是在一段固定的延迟后触发事件处理程序。当您运行上述代码时,您将在控制台中看到两条日志。[JSFiddle 演示在这里 - http://jsfiddle.net/D7GTP/ ]

Actual target: <input class="ui-btn-hidden" type="button" value="click me" data-disabled="false">
Target I get here: Document
Run Code Online (Sandbox Code Playgroud)

为什么e.currentTarget从第 4 行突变到第 7 行?

请注意:有问题的事件是vclick,它是由 jquerymobile 提供的。

Ber*_*rgi 3

为什么e.currentTarget从第 4 行突变到第 7 行?

因为事件冒泡。只有一个事件对象被传递到从上到下的所有注册处理<input>程序document。在每个阶段,currentTarget属性都会更改为当前目标元素。事件离开后document,将被设置为null

然而,对于你来说,情况有点不同。您已经加载了 jQuery 和 jQueryMobile,它们各自添加了自己的事件内容。例如,jQuery构造了规范化Event对象,而 Mobile 似乎又添加了另一个额外的层。您可以尝试检查.originalEvent房产。

为什么现在不一样了?自定义事件构造发生在每个阶段,并且您的侦听器获得一个唯一的对象。它currentTarget没有改变。当您使用普通click事件时,您可以观察到这一点。然而,如果您使用移动设备的vclick事件,则将使用事件委托。在这里,自定义事件对象被重用。当它触发你的处理程序时,currentTarget被设置为<input>. 之后,它会重置为委托绑定到的元素 - document.

当您在超时内记录属性时,您将获得所有修改后的属性 - 而不是与您相关的属性。console.log当您使用事件对象时,也会发生同样的事情(请参阅延迟日志记录)。

长话短说:

当您在回调执行期间访问事件属性时,您可以期望它们是准确的。

当您在触发处理程序访问事件属性时,如果您使用

  • 普通 DOM 事件:currentTarget将会null
  • jQuery 事件:currentTarget将保持不变
  • jQuery 委托事件(包括 jQueryMobile 事件):将currentTarget是实际绑定目标