这背后的原因是因为 Twitter Bootstrap 使用 that.$element.trigger('hidden.bs.modal')(line 997) 来触发它的事件。换句话说,它使用.trigger。
现在 jQuery 使用 ._data 跟踪每个元素的事件处理程序(所有 .on 或 .bind 或 .click 等)。这是因为there isn't any other way to get the event handlers 绑定(使用.addEventListener)到一个元素。所以触发方法实际上只是从._data(element, 'events')和._data(element, 'handle')获取设置的事件监听器/处理程序作为一个数组并运行它们中的每一个。
handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
if ( handle ) {
handle.apply( cur, data );
}
(line 4548)
这意味着无论上下文是什么,如果一个事件通过.addEventListener 绑定,它将不会使用.trigger 运行。这是一个例子。仅在加载时会记录 jquery(由 .trigger 触发)。但是,如果您单击 a 元素,两者都会运行。
$('a')[0].addEventListener('click', function(){console.log('addlistener');}, false);
$('a').on('click', function(){
console.log('jquery');
});
$('a').trigger('click');
DEMO
或者,您 can trigger an event 使用 fireEvent(ie) 和 dispatchEvent(non-ie) 在 javascript 中的元素上。 我不一定理解或知道 jQuery 的.trigger 不这样做的原因,但他们可能有也可能没有。 在a little more research 之后我发现他们没有这样做因为一些较旧的浏览器仅支持每个事件 1 个事件处理程序。
一般来说,我们并未尝试实现仅适用于某些浏览器(和某些事件)但并非全部适用的功能,因为有人会立即提交一个无法正常工作的错误。
虽然我不建议这样做,但您可以通过对引导程序代码进行少量更改来解决此问题。您只需要确保 first 附加了下面的函数(否则您将让侦听器触发两次)。
$(modalID).on('hidden.bs.modal', function (e, triggered) {
var event; // The custom event that will be created
if(!triggered){
return false;
}
e.preventDefault();
e.stopImmediatePropagation();
if (document.createEvent) {
event = document.createEvent("HTMLEvents");
event.initEvent("hidden.bs.modal", true, true);
} else {
event = document.createEventObject();
event.eventType = "hidden.bs.modal";
}
event.eventName = "hidden.bs.modal";
if (document.createEvent) {
this.dispatchEvent(event);
} else {
this.fireEvent("on" + event.eventType, event);
}
});
最后将上面的 Twitter Bootstrap 行改为:
that.$element.trigger('hidden.bs.modal', true)
这是为了让你知道它被触发了,而不是你自己触发的事件。请记住,我没有在模态中尝试过这段代码。虽然它在下面的click 演示中运行良好,但它可能会或可能不会像预期的那样在模态中运行。
DEMO