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

如何禁用模态框弹出后的背景点击并修复记忆游戏计时器异常

解决记忆游戏的两个问题:计时器意外重启与背景点击禁用

先给你理清楚问题根源:计时器重启是因为牌组的点击事件没做状态判断,哪怕游戏结束了还能触发计时逻辑;而背景点击能生效,是因为模态框弹出后没做交互隔离。咱们分两步解决:

1. 模态框弹出后禁止背景点击(两种实用方案)

方案A:添加全屏遮罩层(推荐)

给模态框加一个覆盖整个屏幕的遮罩层,点击背景时实际触发的是遮罩,不会碰到底下的牌组:

<!-- 模态框结构 -->
<div class="modal-overlay"></div>
<div class="modal">
  <!-- 你的模态框内容:总时长、星级展示 -->
</div>

搭配CSS样式:

.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0,0,0,0.3); /* 半透明黑,也可以设为全透明 */
  z-index: 999; /* 层级要比牌组高,比模态框低 */
  display: none; /* 默认隐藏 */
}

/* 游戏结束时,给父容器加这个类来显示遮罩和模态框 */
.game-finished .modal-overlay,
.game-finished .modal {
  display: block;
}

当游戏结束弹出模态框时,给body或者游戏容器加上game-finished类,遮罩就会挡住整个背景,彻底禁止点击。

方案B:用CSS直接禁用牌组交互

如果不想加额外DOM元素,也可以在游戏结束时给牌组容器加pointer-events: none,直接让它失去点击响应:

.game-finished .card-container {
  pointer-events: none;
}

这样模态框弹出后,牌组区域完全不会接收任何点击事件,从根源避免误触发。


2. 修复计时器意外重启的问题

光靠遮罩还不够,最好在计时逻辑里加一层状态判断,双重保险:

首先给游戏加个全局状态变量,比如isGameRunning,初始值为false:

let isGameRunning = false;
let timerInterval; // 存储计时器ID,方便后续清除

然后在牌的点击事件里,先判断游戏状态:

document.querySelectorAll('.card').forEach(card => {
  card.addEventListener('click', () => {
    // 如果游戏已经结束,直接跳出,不执行任何逻辑
    if (!isGameRunning) return;

    // 原来的牌翻转、匹配逻辑...

    // 只有当游戏未启动,且点击的是背面朝上的牌时,才启动计时器
    if (!isGameRunning && card.classList.contains('back-face')) {
      isGameRunning = true;
      startTimer();
    }
  });
});

最后在游戏结束的函数里,更新状态并停止计时器:

function finishGame() {
  // 停止计时器
  clearInterval(timerInterval);
  // 重置计时器显示为0
  document.getElementById('timer').textContent = '00:00';
  // 标记游戏已结束
  isGameRunning = false;
  // 弹出模态框并添加禁用背景的类
  document.body.classList.add('game-finished');
}

这样一来,哪怕遮罩出点小问题,只要isGameRunning是false,点击牌组也不会触发任何逻辑,更不会重启计时器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:31:46