为什么jQuery triggerHandler()有效,但是trigger()没有?

时间:2013-06-14 07:16:26

标签: javascript jquery javascript-events jquery-triggerhandler jquery-trigger

点击使用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来做。)

enter image description here

1 个答案:

答案 0 :(得分:19)

让我们比较jQuery.fn.trigger and jQuery.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 );
    }
}

唯一真正的区别是第四个参数truejQuery.event.trigger赋予triggerHandler

查看jQuery.event.triggerthe argument is called onlyHandlers以及其他内容,the documentation of triggerHandler注意到:

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

我们可以看到where the default behaviour is actually triggered

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

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

onlyHandlers为真(triggerHandler()),这绝不会发生。

因此,对于trigger()情况,它最终会在目标元素上执行click(),这会正确地触发状态更改 - 但事实证明,在trigger()triggerHandler()个案例,点击已经the loop through the eventPath above中正确启动:

// 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做一次。

这可以通过使用检查器单步执行{{1}}方法并看到选择器打开然后再次关闭来验证。

问题是这是否是我们通常所期望的;看起来奇怪的是,在仅有DOM反应的情况下,否则工作的事件触发器会导致双触发。