让我们比较一下jQuery.fn.trigger
和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 );
}
}
唯一真正的区别是第四个参数 ,true
,赋予jQuery.event.trigger
with 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 反应的情况下,一个正常工作的事件触发器会导致双重触发器,这似乎很奇怪。