搜索
首页web前端css教程让我们在JavaScript中创建轻巧的本机活动巴士

Let’s Create a Lightweight Native Event Bus in 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 可以对其进行检查。在那里,我们可以在“元素”→“事件侦听器”选项卡中找到事件。请务必取消选中“祖先”以隐藏绑定到 documentwindow 上的事件。

示例

一个缺点是 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中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
什么是CSS网格?什么是CSS网格?Apr 30, 2025 pm 03:21 PM

CSS网格是创建复杂,响应式Web布局的强大工具。它简化了设计,提高可访问性并提供了比旧方法更多的控制权。

什么是CSS Flexbox?什么是CSS Flexbox?Apr 30, 2025 pm 03:20 PM

文章讨论了CSS FlexBox,这是一种布局方法,用于有效地对齐和分布响应设计中的空间。它说明了FlexBox用法,将其与CSS网格进行了比较,并详细浏览了浏览器支持。

我们如何使用CSS使网站迅速响应?我们如何使用CSS使网站迅速响应?Apr 30, 2025 pm 03:19 PM

本文讨论了使用CSS创建响应网站的技术,包括视口元标签,灵活的网格,流体媒体,媒体查询和相对单元。它还涵盖了使用CSS网格和Flexbox一起使用,并推荐CSS框架

CSS盒装属性有什么作用?CSS盒装属性有什么作用?Apr 30, 2025 pm 03:18 PM

本文讨论了CSS盒装属性,该属性控制了元素维度的计算方式。它解释了诸如Content-Box,Border-Box和Padding-Box之类的值,以及它们对布局设计和形式对齐的影响。

我们如何使用CSS动画?我们如何使用CSS动画?Apr 30, 2025 pm 03:17 PM

文章讨论使用CSS,关键属性并与JavaScript结合创建动画。主要问题是浏览器兼容性。

我们可以使用CSS向我们的项目添加3D转换吗?我们可以使用CSS向我们的项目添加3D转换吗?Apr 30, 2025 pm 03:16 PM

文章讨论了Web项目的3D转换,关键属性,浏览器兼容性和性能注意事项的讨论。(角色计数:159)

我们如何在CSS中添加梯度?我们如何在CSS中添加梯度?Apr 30, 2025 pm 03:15 PM

文章讨论了使用CSS梯度(线性,径向,重复)来增强网站视觉效果,添加深度,焦点和现代美学。

CSS中的伪元素是什么?CSS中的伪元素是什么?Apr 30, 2025 pm 03:14 PM

文章讨论了CSS中的伪元素,它们在增强HTML样式方面的使用以及与伪级的差异。提供实用的例子。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

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

热工具

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。