如何重置JavaScript记忆卡牌游戏?实现卡牌翻回与重新开局
解决方案
你当前的重置按钮仅处理了移除卡牌的flip类,但还有几个核心问题没解决:配对成功的卡牌已被移除点击事件、游戏状态未完全重置、卡牌也没重新洗牌。按以下方式修改即可实现完整的重置功能:
1. 完善重置按钮的处理逻辑
更新按钮点击事件,一次性覆盖所有重置需求:
document.querySelector(".btn").addEventListener("click", () => { // 清除未完成的翻转定时器,避免干扰重置流程 clearTimeout(window.unflipTimer); // 将所有卡牌翻回背面,并重新绑定点击事件 cards.forEach(card => { card.classList.remove("flip"); card.addEventListener("click", flip); }); // 重置游戏状态变量 reset(); // 重新打乱卡牌顺序 shuffle(); });
2. 调整unflip函数,保存定时器引用
为了能在重置时中断未完成的翻转动画,修改unflip函数,把定时器引用存到全局变量:
function unflip() { lock = true; // 保存定时器引用,方便重置时清除 window.unflipTimer = setTimeout(() => { firstCard.classList.remove("flip"); secondCard.classList.remove("flip"); reset(); }, 1000); };
3. 将shuffle改为可重复调用的普通函数
原来的洗牌逻辑是立即执行函数,改成普通函数方便重置时调用:
function shuffle() { cards.forEach(card => { let randomPlace = Math.floor(Math.random() * 12); card.style.order = randomPlace; }); } // 页面加载时执行首次洗牌 shuffle();
修改后的完整代码
"use strict"; const cards = document.querySelectorAll(".memory-card"); let cardFlipped = false; let lock = false; let firstCard, secondCard; function flip() { if(lock) return; if(this === firstCard) return; this.classList.add("flip"); if (!cardFlipped) { cardFlipped = true; firstCard = this; return; } cardFlipped = false; secondCard = this; checkMatch(); }; function checkMatch() { let isMatch = firstCard.dataset.image === secondCard.dataset.image; isMatch ? disable() : unflip(); }; function disable() { firstCard.removeEventListener("click", flip); secondCard.removeEventListener("click", flip); reset(); }; function unflip() { lock = true; // 保存定时器引用 window.unflipTimer = setTimeout(() => { firstCard.classList.remove("flip"); secondCard.classList.remove("flip"); reset(); }, 1000); }; function reset() { [cardFlipped, lock] = [false, false]; [firstCard, secondCard] = [null, null]; }; function shuffle() { cards.forEach(card => { let randomPlace = Math.floor(Math.random() * 12); card.style.order = randomPlace; }); } // 页面初始化洗牌 shuffle(); cards.forEach(card => card.addEventListener("click", flip)); document.querySelector(".btn").addEventListener("click", () => { // 清除未完成的翻转定时器 clearTimeout(window.unflipTimer); // 翻回所有卡牌并重新绑定事件 cards.forEach(card => { card.classList.remove("flip"); card.addEventListener("click", flip); }); reset(); shuffle(); });
修改后,无论游戏中途还是所有卡牌配对完成后点击重置按钮,都会:
- 将所有卡牌翻回背面
- 恢复所有卡牌的点击交互能力
- 重置游戏的状态变量
- 重新打乱卡牌顺序,完全回到初始游戏状态
内容的提问来源于stack exchange,提问作者Luke
相关产品推荐
相关产品推荐

