如何在Modal对象达到完成状态后触发App中的game.play()函数
解决方案:不用轮询,让Modal完成后自动启动游戏
轮询确实是个笨办法,咱们换点更优雅的方案,完全不需要反复盯着状态看。下面给你几个符合前端事件驱动思想的实现方式:
方案1:自定义事件(最推荐,解耦性最好)
这种方式让Modal只负责触发“完成”事件,app.js负责监听事件并执行游戏启动逻辑,两者完全解耦,后续扩展也更方便。
修改Modal类代码
在Modal类里,当用户走完最后一步(currentStep === 4)时,触发一个自定义事件:
constructor(){ this.currentStep = 0; // 把modal元素存为实例属性,方便后续派发事件 this.modal = document.querySelector('#your-modal-element'); // 替换成你的modal实际选择器 } complete() { return this.currentStep >= 4; } activate() { const nextButton = document.querySelector('#next-button'); const firstInstructions = document.querySelector('#first-instructions'); const firstGif = document.querySelector('#first-gif'); nextButton.addEventListener('click', (e) => { if (this.currentStep === 0) { firstInstructions.classList.add('hideMe'); firstGif.classList.remove("hideMe"); // 其他步骤的逻辑... } else if (this.currentStep === 4) { this.modal.classList.add("hideMe"); // 触发自定义事件,通知外部模态框流程完成 const completeEvent = new CustomEvent('modalComplete'); this.modal.dispatchEvent(completeEvent); } this.currentStep++; }); }
修改app.js代码
在app.js里监听这个自定义事件,触发游戏启动:
const game = new Game(); const modal = new Modal(); modal.activate(); // 监听模态框完成事件 modal.modal.addEventListener('modalComplete', () => { game.play(); });
方案2:回调函数(简单直接,适合小型项目)
如果你的场景比较简单,不需要复杂的解耦,可以直接给Modal的activate方法传入一个回调函数,当流程完成时调用它。
修改Modal类代码
activate(onCompleteCallback) { const nextButton = document.querySelector('#next-button'); const firstInstructions = document.querySelector('#first-instructions'); const firstGif = document.querySelector('#first-gif'); nextButton.addEventListener('click', (e) => { if (this.currentStep === 0) { firstInstructions.classList.add('hideMe'); firstGif.classList.remove("hideMe"); // 其他步骤逻辑... } else if (this.currentStep === 4) { this.modal.classList.add("hideMe"); // 调用传入的回调函数 onCompleteCallback(); } this.currentStep++; }); }
修改app.js代码
const game = new Game(); const modal = new Modal(); // 传入回调,Modal完成后自动执行game.play() modal.activate(() => { game.play(); });
方案3:Promise(适合复杂异步流程)
如果你的模态框流程还涉及其他异步操作(比如加载资源、接口请求),用Promise会更灵活,还能结合async/await写出更清晰的代码。
修改Modal类代码
activate() { return new Promise((resolve) => { const nextButton = document.querySelector('#next-button'); const firstInstructions = document.querySelector('#first-instructions'); const firstGif = document.querySelector('#first-gif'); nextButton.addEventListener('click', (e) => { if (this.currentStep === 0) { firstInstructions.classList.add('hideMe'); firstGif.classList.remove("hideMe"); // 其他步骤逻辑... } else if (this.currentStep === 4) { this.modal.classList.add("hideMe"); // 完成时resolve Promise resolve(); } this.currentStep++; }); }); }
修改app.js代码
const game = new Game(); const modal = new Modal(); // 用.then()处理 modal.activate().then(() => { game.play(); }); // 或者用async/await(更简洁) // async function initApp() { // await modal.activate(); // game.play(); // } // initApp();
方案对比
- 自定义事件:最推荐,完全解耦Modal和Game,Modal不需要知道Game的存在,扩展性最好。
- 回调函数:简单易上手,适合小型项目或逻辑简单的场景。
- Promise:适合有多个异步步骤的复杂场景,代码可读性更高。
内容的提问来源于stack exchange,提问作者sco
相关产品推荐
相关产品推荐

