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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:30:51