如何在事件触发时创建消息?基于EventEmitter的节拍歌词消息组件实现技术问询
搞定节拍触发歌词元素的问题
嘿,我看了你的代码,发现两个关键问题导致你的逻辑没跑起来,咱们一步步来修正:
核心问题拆解
- 事件监听搭错了线:你的
Beat类每次节拍触发的是BIT事件(Beat.events.BIT),但Application里却在监听update事件——这就像你在喊"吃饭啦",但别人在等"开饭啦"的信号,自然没反应。 - 歌词索引逻辑不对:你想用
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
相关产品推荐
相关产品推荐

