Twitter Bootstrap。 为什么模态事件在JQuery中工作但在纯JS中不起作用?
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')
( 第997行 )来触发它的事件。 换句话说,它使用.trigger
。
现在,jQuery使用._data
跟踪每个元素的事件处理程序(所有.on
或.bind
或._data
等)。 这是因为没有任何其他方法可以将绑定的事件处理程序 (使用.addEventListener
)绑定到元素。 所以触发器方法实际上只是将._data(element, 'events')
和._data(element, 'handle')
的set事件监听器/处理程序作为一个数组得到并运行它们中的每一个。
handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); if ( handle ) { handle.apply( cur, data ); }
( 第4548行 )
这意味着无论上下文是什么,如果事件通过.trigger
绑定,它将不会使用.trigger
运行。 这是一个例子。 在加载时,将仅记录jquery
(由.trigger
触发)。 如果单击a
元素,则两者都将运行。
$('a')[0].addEventListener('click', function(){console.log('addlistener');}, false); $('a').on('click', function(){ console.log('jquery'); }); $('a').trigger('click');
DEMO
或者,您可以使用fireEvent
(ie)& dispatchEvent
(non-ie)在javascript中触发元素上的事件 。 我不一定理解或知道jQuery的 经过一番研究后,我发现他们没有这样做,因为一些旧的浏览器每个事件只支持1个事件处理程序。 .trigger
没有这样做的推理,但他们可能有也可能没有。
一般来说,我们没有尝试实现仅适用于某些浏览器(和某些事件)但不是全部的function,因为有人会立即提交一个无法正常工作的错误。
虽然我不推荐它,但你可以通过对bootstraps代码进行少量更改来解决这个问题。 你只需要确保首先附加下面的函数(或者你将有两次触发器)。
$(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