推特引导程序.为什么模态事件在 JQuery 中有效,而在纯 JS 中无效? [英] Twitter Bootstrap. Why do modal events work in JQuery but NOT in pure JS?

查看:16
本文介绍了推特引导程序.为什么模态事件在 JQuery 中有效,而在纯 JS 中无效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Twitter Bootstrap 模态对话框有一组可用于回调的事件.

The Twitter Bootstrap modal dialog has a set of events that can be used with callbacks.

这是一个jQuery的例子:

Here is an example in jQuery:

    $(modalID).on('hidden.bs.modal', function (e) {

        console.log("hidden.bs.modal");
    });

但是,当我将此方法转录到 JS 时,事件 'hidden.bs.modal' 不起作用.使用 'click' 确实有效:

However, when I transcribe this method to JS the event 'hidden.bs.modal' does not work. Using 'click' does work:

    document.querySelector(modalID).addEventListener('hidden.bs.modal', function(e) {

        console.log("hidden.bs.modal");
    }, false);

这些 Bootstrap 事件是否只能与 jQuery 一起使用?为什么?

Are these Bootstrap events only useable with jQuery? Why?

谢谢,
道格

推荐答案

这背后的原因是因为 Twitter Bootstrap 使用了 that.$element.trigger('hidden.bs.modal')(第 997 行) 来触发它的事件.换句话说,它使用 .trigger.

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.

现在 jQuery 使用 跟踪每个元素的事件处理程序(所有 .on.bind.click 等)._数据.这是因为 没有任何其他方法可以获取绑定的事件处理程序(使用 .addEventListener) 到一个元素.所以触发器方法实际上只是从 ._data(element, 'events') & 获取设置的事件侦听器/处理程序.._data(element, 'handle') 作为一个数组并运行它们中的每一个.

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 );
}

(第 4548 行)

这意味着无论什么上下文,如果一个事件是通过 .addEventListener 绑定的,它就不会使用 .trigger 运行.这是一个例子.加载时只记录 jquery(由 .trigger 触发).但是,如果您单击 a 元素,两者都会运行.

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');

演示

或者,您可以使用fireEvent在javascript中的元素上触发事件(即) &dispatchEvent(非即).我不一定理解或知道 jQuery 的 .trigger 不这样做的原因,但他们可能有也可能没有.多一点研究 我发现他们不这样做,因为一些较旧的浏览器只支持每个事件 1 个事件处理程序.

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);
    }
});

最后将 Twitter Bootstrap 行从上面改为:

Finally change the Twitter Bootstrap line from above to:

that.$element.trigger('hidden.bs.modal', true)

这是为了让您知道它是被触发的,而不是您自己触发的事件.请记住,我还没有用模态尝试过这段代码.尽管它在下面的 click 演示中运行良好,但它可能会也可能不会在模态中按预期运行.

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.

演示

这篇关于推特引导程序.为什么模态事件在 JQuery 中有效,而在纯 JS 中无效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆