jQuery: 事件触发器trigger, 事件模型, 默认行为执行顺序, Native click won’t be triggered by jQuery

一般来讲,直接 trigger 一个 a 标签的 click 事件是不被浏览器允许的,正常情况下都是由用户的 click 事件来触发一个「点击动作」,在这个「动作」中,我们可以调用触发其他的 click 事件,就好像用户点在了其他的标签上。按照长期使用 jQuery 的思路,一般就会直接使用下面的方式来触发:

$('a').click();

或者是:

$('a').trigger('click');

很遗憾的是,这样是不行的,jQuery 并不会为 a 标签提供 native click 事件的触发,而我们想要做这件事情就需要用原生的 DOM element 来做:

$('a').get(0).click();

至于为什么?我找到了一个说法,是 Learn jQuery 上的一篇文章:Triggering Event Handlers。它说到:

The .trigger() function cannot be used to mimic native browser events, such as clicking on a file input box or an anchor tag.

This is because, there is no event handler attached using jQuery’s event system that corresponds to these events.

.trigger() 函数不能用来模拟 native browser events,比如 click 一个 file input box 或是 a 标签。

这是因为,jQuery 的 event system 中没有对应于这些事件的 event handler。

Why

怎么理解呢?我在 stackoverflow 上问了同样的问题:Why jQuery cannot trigger native click on an anchor tag

得到了这样的答案:

.trigger()

Execute all handlers and behaviors attached to the matched elements for the given event type.

简单说来,就是从 jQuery 的视角来看,.trigger() 只会去执行所有通过 jQuery 注册的函数。这看上去很有道理,答案还有附有一个 jsFiddle,可以看到,使用 native 方法绑定的事件也是不会被 jQuery 调用的(显然不会……)。

所以问题的答案就是这样,jQuery 不会去触发没有通过 jQuery 注册的函数,而点击链接所伴随的打开新窗口的事件是类似于一种 behaviors 的存在。

 

使用 dispatchEvent 派发事件来实现:

向一个指定的事件目标派发一个事件,  以合适的顺序触发受影响的 事件目标。标准事件处理规则(包括事件捕获和可选的冒泡过程)同样适用于通过手动的使用dispatchEvent()方法派发的事件。

语法

cancelled = !target.dispatchEvent(event)
  • event 是要被派发的事件对象。
  • target 被用来初始化 事件 和 决定将会触发 目标.
  • 当该事件是可取消的(cancleable为true)并且至少一个该事件的 事件处理方法 调用了Event.preventDefault(),则返回值为false;否则返回true

如果该被派发的事件的事件类型(event’s type)在方法调用之前没有被经过初始化被指定,就会抛出一个 UNSPECIFIED_EVENT_TYPE_ERR 异常,或者如果事件类型是null或一个空字符串. event handler 就会抛出未捕获的异常; 这些 event handlers 运行在一个嵌套的调用栈中: 他们会阻塞调用直到他们处理完毕,但是异常不会冒泡。

具体解决方法:

$(selector).on(eventType, function() {$(this).length > 0 ? $(this)[0].dispatchEvent(new Event(eventType)) : null;});

例如:

$('select[name="country"]').on('change', function() {$(this).length > 0 ? $(this)[0].dispatchEvent(new Event('change')) : null;});

这样的话,再执行

$('select[name="country"]').val('US').change();

就可以了!

jQuery: 事件触发器trigger, 事件模型, 默认行为执行顺序, Native click won't be triggered by jQuery
jQuery: 事件触发器trigger, 事件模型, 默认行为执行顺序, Native click won’t be triggered by jQuery

 

本文:jQuery: 事件触发器trigger, 事件模型, 默认行为执行顺序, Native click won’t be triggered by jQuery