You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在事件触发时创建消息?基于EventEmitter的节拍歌词消息组件实现技术问询

搞定节拍触发歌词元素的问题

嘿,我看了你的代码,发现两个关键问题导致你的逻辑没跑起来,咱们一步步来修正:

核心问题拆解

  1. 事件监听搭错了线:你的Beat类每次节拍触发的是BIT事件(Beat.events.BIT),但Application里却在监听update事件——这就像你在喊"吃饭啦",但别人在等"开饭啦"的信号,自然没反应。
  2. 歌词索引逻辑不对:你想用bit参数当歌词数组的索引,但Beat的emit根本没传这个参数,而且也没个计数器帮你按顺序走歌词。

修正后的代码

Application类修改版

import EventEmitter from "eventemitter3";
import Beat from "./Beat";

export default class Application extends EventEmitter {
  static get events() {
    return {
      READY: "ready",
    };
  }

  constructor() {
    super();
    this._beat = new Beat();
    this._create();
    this.emit(Application.events.READY);
  }

  _create() {
    const lyrics = ["Ah", "ha", "ha", "ha", "stayin' alive", "stayin' alive"];
    let currentLyricIndex = 0; // 专门维护歌词的当前位置

    // 监听Beat正确的BIT事件
    this._beat.on(Beat.events.BIT, () => {
      const message = document.createElement("div");
      message.classList.add("message");
      // 用当前索引取歌词
      message.innerText = lyrics[currentLyricIndex];
      document.querySelector(".main").appendChild(message);

      // 索引自增,到末尾就重置实现循环
      currentLyricIndex = (currentLyricIndex + 1) % lyrics.length;
    });
  }
}

改动说明

  • 事件配对:现在监听的是Beat.events.BIT,和Beat类触发的事件完全对应,节拍一来就能触发歌词创建。
  • 循环歌词逻辑:用currentLyricIndex计数器跟踪当前歌词位置,每次节拍后索引+1,通过% lyrics.length让索引在歌词数组长度内循环,唱完一遍自动从头再来。
  • 移除无效参数:Beat的emit没传任何参数,所以回调里不需要bit这个没用的参数,换成咱们自己的计数器就好。

如果你不想循环播放,只想唱一轮就停,那可以把索引更新改成这样:

if (currentLyricIndex < lyrics.length - 1) {
  currentLyricIndex++;
} else {
  // 可选:播放完一轮后取消监听,避免继续创建元素
  this._beat.off(Beat.events.BIT);
}

内容的提问来源于stack exchange,提问作者koko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 11:57:50