2

triggerHandler()使用作品点击一个元素:

$element = $('#gwt-debug-location-pill-edit-div:visible');
$element.triggerHandler('click');

但是,使用 , 单击它trigger()不会:

$element.trigger('click');

这是为什么?


要复制它(在 Firefox 和 Chrome 中):

  • 转到https://adwords.google.com/select/home,然后使用您的凭据登录
  • 工具和分析->关键字规划师
  • 展开“输入或上传关键字以查看其效果”
  • 使用浏览器的控制台,尝试通过上面的两种方法单击位置框(在下面的屏幕截图中标记为红色)(您需要将 jQuery 注入页面。我使用jQuerify来做到这一点。)

在此处输入图像描述

4

1 回答 1

19

让我们比较一下jQuery.fn.triggerjQuery.fn.triggerHandler

trigger: function( type, data ) {
    return this.each(function() {
        jQuery.event.trigger( type, data, this );
    });
},
triggerHandler: function( type, data ) {
    var elem = this[0];
    if ( elem ) {
        return jQuery.event.trigger( type, data, elem, true );
    }
}

唯一真正的区别是第四个参数 ,true,赋予jQuery.event.triggerwith triggerHandler

看着jQuery.event.trigger参数被称为onlyHandlers,除其他外,注释的文档triggerHandler

  • .triggerHandler() 方法不会导致事件的默认行为发生(例如表单提交)。

我们可以看到实际触发默认行为的位置

// If nobody prevented the default action, do it now
if ( !onlyHandlers && !event.isDefaultPrevented() ) {

如果onlyHandlers为 false ( trigger()),并且没有事件处理程序停止执行默认事件,则将执行默认操作。

onlyHandlers如果为真 ( triggerHandler()),这将永远不会发生。

因此,对于这种trigger()情况,它最终click()在目标元素上执行,这会正确触发状态更改——但事实证明,在这两种情况下trigger()triggerHandler()点击已经通过上面的 eventPath 在循环中正确触发:

// Native handler
handle = ontype && cur[ ontype ];
if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {

所以trigger('click')最终会单击元素两次(!)——大概是因为click()不会返回 false,所以永远不会阻止事件默认操作——而triggerHandler('click')只会执行一次。

这可以通过jQuery.event.trigger使用检查器逐步执行该方法并看到选择器打开然后再次关闭来验证。

问题是这是否是我们通常所期望的;在仅 DOM 反应的情况下,一个正常工作的事件触发器会导致双重触发器,这似乎很奇怪。

于 2013-06-17T13:26:34.477 回答