Twitter Bootstrap模态对话框具有一组可与回调一起使用的事件。
这是jQuery中的一个示例:
$(modalID).on('hidden.bs.modal', function (e) {
console.log("hidden.bs.modal");
});
但是,当我将此方法转录为JS时,事件'hidden.bs.modal'不起作用。使用'click'确实有效:
document.querySelector(modalID).addEventListener('hidden.bs.modal', function(e) {
console.log("hidden.bs.modal");
}, false);
这些Bootstrap事件仅可用于jQuery吗?为什么?
谢谢,道格
这背后的原因是因为Twitter Bootstrap使用that.$element.trigger('hidden.bs.modal')
(line 997)来触发其事件。换句话说,它使用.trigger
。
现在jQuery使用.trigger
跟踪每个元素的事件处理程序(所有.on
或.bind
或.click
等)。这是因为._data
被绑定(使用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(ie)和fireEvent
(non-ie)在javascript中使用元素。 我不一定理解或不知道jQuery的在dispatchEvent
不这样做的原因,但是他们可能有一个也可能没有。.trigger
之后,我发现他们不这样做是因为有些旧的浏览器每个事件仅支持1个事件处理程序。
[通常,我们并未尝试实现仅在某些浏览器(和某些事件)上但不适用于所有浏览器的功能,因为有人会立即提交一个无法正常使用的错误。
尽管我不建议这样做,但是您可以通过对引导程序代码进行最少的更改来解决此问题。您只需要确保下面的功能已附加first(否则您的监听器将触发两次)。
a little more research
最后将Twitter Bootstrap行从上方更改为:
$(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);
}
});
这是因为您知道它被触发了,而不是您随后自焚的事件。请记住,我还没有尝试使用模态代码。尽管它在下面的that.$element.trigger('hidden.bs.modal', true)
演示中确实可以正常工作,但对于模态它可能无法正常工作。
click
本机Javascript解决方案。这是我在没有JQuery的情况下的方法。有点晚了,但是请接受我的代码作为答案。
DEMO
兼容性://my code ----------------------------------------
export const ModalHiddenEventListener = (el, fn, owner) => {
const opts = {
attributeFilter: ['style']
},
mo = new MutationObserver(mutations => {
for (let mutation of mutations) {
if (mutation.type === 'attributes'
&& mutation.attributeName ==='style'
&& mutation.target.getAttribute('style') === 'display: none;') {
mo.disconnect();
fn({
owner: owner,
element: mutation.target
});
}
}
});
mo.observe(el, opts);
};
//your code with Bootstrap modal id='modal'-------
const el = document.getElementById('modal'),
onHide = e => {
console.log(`hidden.bs.modal`);
};
ModalHiddenEventListener(el, onHide, this);