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

如何在JavaScript中等待鼠标输入并触发后移除事件监听

解决JavaScript游戏循环等待鼠标输入的问题

你的问题根源在于JavaScript是单线程的,while循环会直接阻塞整个事件循环——浏览器根本没时间处理用户的点击事件,循环就已经跑完了,所以监听器刚加上就被移除,完全达不到等待的效果。

要实现“等待用户输入再进入下一回合”的逻辑,得用异步编程的方式,结合Promise和async/await来让代码“暂停”等待用户操作,同时不阻塞浏览器的交互。

具体实现步骤:

  1. 先封装一个等待点击的函数,返回Promise,当用户点击元素时完成Promise:
function waitForClick(element) {
  return new Promise(resolve => {
    // 定义单次点击的处理函数
    function handleClick(event) {
      // 点击后立即移除监听器,避免重复触发
      element.removeEventListener('click', handleClick);
      // 把点击事件对象传给后续逻辑
      resolve(event);
    }
    element.addEventListener('click', handleClick);
  });
}
  1. 把游戏逻辑改成异步函数,用await等待用户点击后再执行下一回合:
async function runGame() {
  let turn = 1;
  const maxTurns = 3; // 你设定的回合上限

  while (turn <= maxTurns) {
    if (turn % 2 !== 0) {
      // 玩家1回合:只给玩家1的手牌绑定点击监听
      console.log('玩家1回合,请点击手牌');
      // 等待玩家1点击,点击后才会继续执行
      const clickEvent = await waitForClick(player1hand);
      // 这里写玩家1点击后的逻辑,替换原来handactive里的代码
      // 比如:console.log('玩家1点击了', clickEvent.target);
    } else {
      // 玩家2回合:只给玩家2的手牌绑定点击监听
      console.log('玩家2回合,请点击手牌');
      const clickEvent = await waitForClick(player2hand);
      // 这里写玩家2点击后的逻辑
      // 比如:console.log('玩家2点击了', clickEvent.target);
    }
    turn++;
  }

  // 回合结束,游戏结束逻辑
  console.log('游戏结束');
}

// 启动游戏
runGame();

为什么这样可行?

  • await会暂停异步函数的执行,直到Promise完成,但不会阻塞整个浏览器的事件循环——浏览器可以正常处理用户的点击、渲染等操作。
  • 每个回合只会给当前玩家的手牌绑定点击监听器,而且点击后会立即移除该监听器,不会出现多个监听器冲突的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 10:25:12