让我们在JavaScript中创建轻巧的本机活动巴士
事件总线是一种设计模式(虽然我们将在这里讨论JavaScript,但它在任何语言中都是一种设计模式),可用于简化不同组件之间的通信。它也可以被认为是发布/订阅或 pubsub。
其思想是,组件可以监听事件总线以了解何时执行其操作。例如,“选项卡面板”组件可能会监听指示其更改活动选项卡的事件。当然,这可能是由单击其中一个选项卡引起的,因此完全在该组件内处理。但是,使用事件总线,其他一些元素可以告诉选项卡进行更改。想象一下表单提交导致用户需要在特定选项卡中收到警报的错误,因此表单向事件总线发送消息,指示选项卡组件将活动选项卡更改为包含错误的选项卡。这就是它在事件总线上看起来的样子。
这种情况的伪代码如下所示……
// 选项卡组件 Tabs.changeTab = id => { // 更改活动选项卡的DOM操作。 }; MyEventBus.subscribe("change-tab", Tabs.changeTab(id)); // 其他组件... // 发生某些事情,然后: MyEventBus.publish("change-tab", 2);
您是否需要 JavaScript 库来实现此功能?(技巧问题:您永远不需要 JavaScript 库)。好吧,有很多选择:
- PubSubJS
- EventEmitter3
- Postal.js
- jQuery 甚至支持自定义事件,这与这种模式高度相关。
此外,请查看 Mitt,这是一个仅 200 字节 gzip 的库。这种简单的模式激发了人们以尽可能简洁的方式自己解决它的灵感。
让我们自己动手吧!我们根本不使用任何第三方库,而是利用 JavaScript 中已经内置的事件侦听系统,即我们都熟悉和喜爱的 addEventListener
。
首先,一些上下文
JavaScript 中的 addEventListener
API 是 EventTarget
类的成员函数。我们可以将点击事件绑定到按钮的原因是(HTMLButtonElement
)的原型接口间接继承自 EventTarget
。
与大多数其他 DOM 接口不同,可以使用 new
关键字直接创建 EventTarget
。它在所有现代浏览器中都受支持,但只是最近才支持。正如我们在上面的屏幕截图中看到的,Node
继承了 EventTarget
,因此所有 DOM 节点都有方法 addEventListener
。
诀窍
我建议使用一种极其轻量级的 Node 类型作为我们的事件侦听总线:HTML 注释(<!-- -->
)。
对于浏览器渲染引擎,HTML 注释只是代码中的注释,除了为开发人员提供描述性文本之外,没有任何功能。但是,由于注释仍然是用 HTML 编写的,因此它们最终作为真实的节点出现在 DOM 中,并具有自己的原型接口——Comment
——它继承自 Node
。
Comment
类可以直接从 new
创建,就像 EventTarget
一样:
const myEventBus = new Comment('my-event-bus');
我们也可以使用古老但广泛支持的 document.createComment
API。它需要一个数据参数,即注释的内容。它甚至可以是空字符串:
const myEventBus = document.createComment('my-event-bus');
现在我们可以使用 dispatchEvent
发出事件,它接受一个 Event
对象。要传递用户定义的事件数据,请使用 CustomEvent
,其中 detail
字段可用于包含任何数据。
myEventBus.dispatchEvent( new CustomEvent('event-name', { detail: 'event-data' }) );
Internet Explorer 9-11 支持 CustomEvent
,但没有任何版本支持 new CustomEvent
。使用 document.createEvent
模拟它很复杂,因此如果 IE 支持对您很重要,则有一种方法可以对其进行填充。
现在我们可以绑定事件侦听器:
myEventBus.addEventListener('event-name', ({ detail }) => { console.log(detail); // => event-data });
如果事件打算只触发一次,我们可以使用 { once: true }
进行一次性绑定。其他选项不适合这里。要删除事件侦听器,我们可以使用原生的 removeEventListener
。
调试
绑定到单个事件总线的事件数量可能非常大。如果您忘记删除它们,也可能存在内存泄漏。如果我们想知道有多少事件绑定到 myEventBus
呢?
myEventBus
是一个 DOM 节点,因此浏览器中的 DevTools 可以对其进行检查。在那里,我们可以在“元素”→“事件侦听器”选项卡中找到事件。请务必取消选中“祖先”以隐藏绑定到 document
和 window
上的事件。
示例
一个缺点是 EventTarget
的语法略显冗长。我们可以为它编写一个简单的包装器。下面是 TypeScript 中的演示:
class EventBus<detailtype any> { private eventTarget: EventTarget; constructor(description = '') { this.eventTarget = document.appendChild(document.createComment(description)); } on(type: string, listener: (event: CustomEvent<detailtype>) => void) { this.eventTarget.addEventListener(type, listener); } once(type: string, listener: (event: CustomEvent<detailtype>) => void) { this.eventTarget.addEventListener(type, listener, { once: true }); } off(type: string, listener: (event: CustomEvent<detailtype>) => void) { this.eventTarget.removeEventListener(type, listener); } emit(type: string, detail?: DetailType) { return this.eventTarget.dispatchEvent(new CustomEvent(type, { detail })); } } // 用法 const myEventBus = new EventBus<string>('my-event-bus'); myEventBus.on('event-name', ({ detail }) => { console.log(detail); }); myEventBus.once('event-name', ({ detail }) => { console.log(detail); }); myEventBus.emit('event-name', 'Hello'); // => Hello Hello myEventBus.emit('event-name', 'World'); // => World</string></detailtype></detailtype></detailtype></detailtype>
下面的演示提供了编译后的 JavaScript。
就是这样!我们刚刚创建了一个无依赖的事件侦听总线,一个组件可以通知另一个组件更改以触发操作。执行此类操作不需要完整的库,并且它开启的可能性是无限的。
以上是让我们在JavaScript中创建轻巧的本机活动巴士的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

您是否曾经在项目上需要一个倒计时计时器?对于这样的东西,可以自然访问插件,但实际上更多

在元素个数不固定的情况下如何通过CSS选择第一个指定类名的子元素在处理HTML结构时,常常会遇到元素个数不�...

关于Flex布局中紫色斜线区域的疑问在使用Flex布局时,你可能会遇到一些令人困惑的现象,比如在开发者工具(d...

格子呢是一块图案布,通常与苏格兰有关,尤其是他们时尚的苏格兰语。在Tartanify.com上,我们收集了5,000多个格子呢
