如何在JavaScript(或jQuery)中实现自定义广播事件? [英] How are custom broadcast events implemented in JavaScript (or jQuery)?

查看:373
本文介绍了如何在JavaScript(或jQuery)中实现自定义广播事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现一个可以广播的自定义事件,而不是发送到特定目标。只有那些已经注册为这种事件的听众的元素才会收到他们。

I want to implement a custom event that can be "broadcast", rather than sent to specific targets. Only those elements that have registered themselves as listeners for such events will receive them.

我想到的内容如下:

首先,在代码的各个不同的地方,将出现

First, in various places of the code, there would be statements of the form

some_subscriber.on_signal( 'some_signal', some_handler );

我使用的是信号 广播事件的缩写。在上面的表达式中,通过为它提供一个处理程序, some_subscriber 将其自身注册为一种类型(称为some_signal)的侦听器。

I'm using the term signal as shorthand for "broadcast event". In the expression above, some_subscriber registers itself as a listener of one type (called 'some_signal') of such signals, by providing a handler for it.

在代码的其他地方,将会出现

Elsewhere in the code, there would be statements of the form

publisher.signal_types[ 'some_signal' ].broadcast( event_data );

当这些语句被执行时,会生成一个新的事件,并且广播。通过这个我的意思是调用广播方法的代码没有关于它发出的信号的听众的直接信息。

When statements like these get executed, a new event is generated and "broadcast". By this I mean that the code that calls the broadcast method has no direct information about the listeners for the signal it is issuing.

我已经在这个jsFiddle中实现了这个想法的草图,主要是为了说明我在 1 之间的话中所描述的内容。 (这当然不是生产级,我并不特别相信可以这样做。)

I have implemented a sketch of this idea in this jsFiddle, mostly in order to illustrate what I described in words above1. (It's certainly not production-grade, and I'm not particularly confident that it could be made so.)

这个实现的关键要素如下。首先,发布商对象不会跟踪他们的订阅者,这可以在为这样的发布商实施工厂方法时看到,如下所示:

The key elements of this implementation are the following. First, publisher objects do not keep track of their subscribers, as can be seen in the implementation of a factory method for such a publisher, shown below:

function make_publisher ( signal_types ) {

    // ...

    var _
    ,   signal = {}
    ,   ping = function ( type ) {
                   signal[ type ].broadcast( ... );
               }
    ;

    signal_types.forEach( function ( type ) {
                             signal[ type ] = $.register_signal_type( type );
                         } );

    return { signal_types: signal_types, ping: ping };
}

此发布商对象仅显示两个项目:广播信号的类型 signal_types )和一个 ping 方法。当调用 ping 方法时,发布者通过广播响应一个信号:

This publisher object exposes only two items: the types of signals it broadcasts (in signal_types), and a ping method. When its ping method is invoked, the publisher responds by broadcasting a signal:

signal[ type ].broadcast( ... )

第二,在代码的其他地方,用户注册自己作为这些代码的听众广播信号,像这样

Second, elsewhere in the code, subscribers register themselves as listeners of these broadcast signals, like so

    $( some_selector ).on_signal( signal_type, some_handler );

注意:基本上不可能说明使用该方案的理由一个既小又现实的例子。这样做的原因在于,这种方案的优点在于它支持发布者代码和用户代码之间的非常松散的耦合,而这是一个在一个小例子中永远不必要的功能。相反,在一个小例子中,实现这种松散耦合的代码总是不必要地复杂化。因此,重要的是要记住,这种明显的过度复杂性是上下文的工件。松散耦合在较大的项目中非常有用。特别是,通过发布者/订阅者类型模式的松散耦合是MVC的基本特征之一。

Note: It is basically impossible to illustrate the rationale for this scheme using an example that is both small and realistic. The reason for this is that the strength of this scheme is that it supports very loose coupling between the publisher code and subscriber code, and this is a feature that is never necessary in a small example. On the contrary, in a small example, code that implements such loose coupling invariably comes across as unnecessarily complex. It is therefore important to keep in mind that this apparent excess complexity is an artifact of the context. Loose coupling is very useful in larger projects. In particular, loose coupling via a publisher/subscriber-type pattern is one of the essential features of MVC.


我的问题是:是否有更好的(或至少更标准)的方式来实现广播自定义事件的这种效果?

My question is: is there a better (or at least more standard) way to achieve this effect of "broadcasting" custom events?

(我对基于jQuery的答案以及纯JS都感兴趣)。

(I'm interested in both jQuery-based answers as well as "pure JS" ones.)

1 这个帖子的一个较早的命运版本遇到了几乎普遍的不理解,(当然)表决。除了一个例外,我所有的评论都对这个帖子的前提提出了质疑,一个直接质疑我对事件驱动程序设计的基础知识的掌握等等。我希望通过提出一个至关重要的工作实例它不会像我在单词中描述的那样完全不可思议。幸运的是,一个有用的评论,我已经得到那个早期的帖子告诉我的功能 jQuery.Callbacks 。这确实是一个有用的提示;在帖子中提到的草图实现是基于 jQuery.Callbacks

1An earlier, ill-fated version of this post was met with almost universal incomprehension, and (of course) the all-too-typical down-voting. With one exception, all the comments I got challenged the very premises of the post, and one directly questioned my grasp of the basics of event-driven programming, etc. I'm hoping that by presenting a working example of what I mean at least it won't come across as utterly inconceivable as it did when I described it in words alone. Luckily, the one helpful comment I did get on that earlier post informed me of the function jQuery.Callbacks. This was indeed a useful tip; the sketch implementation mentioned in the post is based on jQuery.Callbacks.

推荐答案

好吧

所以我想你可以做的是使用原生的 dispatchEvent addEventListener 方法,并使用 文档 作为唯一的发布订阅这些事件。如下:

So I think what you can do is use the native dispatchEvent and addEventListener methods and use document as the only element for both publishing and subscribing to those events. Something like:

var myCustomEvent = new Event('someEvent');
document.dispatchEvent(myCustomEvent);
...
document.addEventListener('someEvent', doSomething, false);

要跨浏览器,您可以:

var myCustomEvent = new Event('someEvent');
document.dispatchEvent(myCustomEvent);
...
if (document.addEventListener) {
    document.addEventListener('someEvent', doSomething, false);
} else {
    document.attachEvent('someEvent', doSomething);
}

您可以阅读更多关于主题的内容这里 here 。希望这有帮助。

You can read more on the subject here and here. Hope this helps.

这篇关于如何在JavaScript(或jQuery)中实现自定义广播事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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