The reasoning behind this is because Twitter Bootstrap uses that.$element.trigger('hidden.bs.modal')
(line 997) to trigger it's events. In other words it uses .trigger
.
Now jQuery keeps track of each element's event handlers (all .on
or .bind
or .click
etc) using ._data
. This is because there isn't any other way to get the event handlers that are bound (using .addEventListener
) to an element. So the trigger method actually just get's the set event listener(s)/handler(s) from ._data(element, 'events')
& ._data(element, 'handle')
as an array and runs each of them.
handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
if ( handle ) {
handle.apply( cur, data );
}
(line 4548)
This means that no matter what context is, if an event is bound via .addEventListener
it will not run using .trigger
. Here's an example. On load only jquery
will be logged (triggered by .trigger
). If you click the a
element though, both will run.
$('a')[0].addEventListener('click', function(){console.log('addlistener');}, false);
$('a').on('click', function(){
console.log('jquery');
});
$('a').trigger('click');
DEMO
Alternatively, you can trigger an event on an element in javascript using fireEvent
(ie) & dispatchEvent
(non-ie). I don't necessarily understand or know the reasoning of jQuery's .trigger
not doing this, but they may or may not have one. After a little more research I've found that they don't do this because some older browsers only supported 1 event handler per event.
In general we haven't tried to implement functionality that only works on some browsers (and some events) but not all, since someone will immediately file a bug that it doesn't work right.
Although I do not recommend it, you can get around this with a minimal amount of changes to bootstraps code. You would just have to make sure that the function below is attached first (or you will have listeners firing twice).
$(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);
}
});
Finally change the Twitter Bootstrap line from above to:
that.$element.trigger('hidden.bs.modal', true)
This is so you know its being triggered and not the event that you're firing yourself after. Please keep in mind I have not tried this code with the modal. Although it does work fine on the click
demo below, it may or may not work as expected with the modal.
DEMO