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

如何用jQuery重置记忆游戏并实现卡片重新洗牌

问题解决:记忆游戏新游戏按钮无法重新洗牌

核心问题在于你每次洗牌都是直接修改同一个cards数组,且未保留原始卡片的基准副本,同时存在事件重复绑定、游戏胜利后DOM未恢复的问题。以下是修复步骤和完整代码:

问题分析

  • 无原始卡片副本:当前app.cards是唯一数据源,多次洗牌后是在已打乱的数组上继续操作,无法回到初始配对状态
  • 重复绑定点击事件:每次调用app.init()都会执行clickHandlers,导致卡片被多次绑定点击事件,触发逻辑混乱
  • newGame函数存在错误:empty()方法传参错误,未恢复unmatched类,游戏胜利后未还原原始卡片DOM

修复方案

  1. 添加原始卡片基准数组,每次新游戏时从基准数组复制一份用于洗牌
  2. 将点击事件绑定移到初始化阶段,避免重复绑定
  3. 完善newGame函数,恢复卡片状态与DOM结构

完整修复代码

JavaScript 代码

$(document).ready(function() {
  var app = {
    // 保存原始卡片基准集合,每次新游戏都从这里复制
    originalCards: ["bmw.jpg", "bmw.jpg", "Daisy.jpg", "Daisy.jpg", "koira.jpg", "koira.jpg", "Macarons.jpg", "Macarons.jpg", "owl.jpg", "owl.jpg", "shakki.jpg", "shakki.jpg"],
    cards: [],
    init: function() {
      // 从基准数组复制一份新的卡片数组
      app.cards = [...app.originalCards];
      app.shuffle();
    },

    shuffle: function() {
      var random = 0;
      var temp = 0;
      // 用let声明循环变量,避免全局变量污染
      for (let i = 1; i < app.cards.length; i++) {
        random = Math.round(Math.random() * i);
        temp = app.cards[i];
        app.cards[i] = app.cards[random];
        app.cards[random] = temp;
      }
      app.assignCards();
      console.log('Shuffled Card Array: ' + app.cards);
    },
    assignCards: function() {
      $('.card').each(function(index) {
        $(this).attr('data-card-value', app.cards[index]);
      });
    },
    checkMatch: function() {
      if ($('.selected').length == 2) {
        if ($('.selected').first().data('cardValue') == $('.selected').last().data('cardValue')) {
          $('.selected').each(function() {
            $(this).animate({ opacity: 0 }).removeClass('unmatched');
          });
          $('.selected').removeClass('selected');
          app.checkWin();
        } else {
          setTimeout(function() {
            $('.selected').html('').removeClass('selected');
          }, 500);
        }
      }
    },
    checkWin: function() {
      if ($('.unmatched').length === 0) {
        $('.main').html('<h1>You Won!</h1>');
      }
    },
  };

  // 只绑定一次点击事件,避免重复绑定
  $('.card').on('click', function() {
    $(this).html('<img src="' + $(this).data('cardValue') + '">').addClass('selected');
    app.checkMatch();
  });

  app.init();

  $('.al').on('click', function() {
    newGame();
    app.init();
  });

  function newGame() {
    // 恢复游戏胜利后的DOM结构
    if ($('.main h1').length > 0) {
      $('.main').html(`
        <div class="card unmatched"></div>
        <div class="card unmatched"></div>
        <div class="card unmatched"></div>
        <div class="card unmatched"></div>
        <div class="card unmatched"></div>
        <div class="card unmatched"></div>
        <div class="card unmatched"></div>
        <div class="card unmatched"></div>
        <div class="card unmatched"></div>
        <div class="card unmatched"></div>
        <div class="card unmatched"></div>
        <div class="card unmatched"></div>
      `);
      // 重新绑定卡片点击事件(DOM被替换后需要重新绑定)
      $('.card').on('click', function() {
        $(this).html('<img src="' + $(this).data('cardValue') + '">').addClass('selected');
        app.checkMatch();
      });
    }
    // 清空卡片内容,恢复初始状态
    $('.card').empty().removeClass('selected').animate({ opacity: 1 }).addClass('unmatched');
  }
});

HTML 代码

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1> Memory Game </h1>

<button class="al">New Game</button>

<main class="main">
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
  <div class="card unmatched"></div>
</main>

<div class="memory-game">
  <img class="front" src="bmw.jpg" alt="bmw">
  <img class="front" src="Daisy.jpg" alt="daisy">
  <img class="front" src="Daisy.jpg" alt="daisy">
  <img class="front" src="koira.jpg" alt="koira">
  <img class="front" src="koira.jpg" alt="koira">
  <img class="front" src="Macarons.jpg" alt="maca">
  <img class="front" src="Macarons.jpg" alt="maca">
  <img class="front" src="owl.jpg" alt="owl">
  <img class="front" src="owl.jpg" alt="owl">
  <img class="front" src="shakki.jpg" alt="shakki">
  <img class="front" src="shakki.jpg" alt="shakki">
</div>

关键修复点说明

  • 新增originalCards存储初始配对卡片,每次新游戏都复制一份全新数组用于洗牌,确保每次都是基于原始配对打乱
  • 将卡片点击事件绑定移到初始化外部,仅绑定一次;游戏胜利后DOM被替换时,重新绑定事件
  • 完善newGame函数,恢复卡片的unmatched类、透明度、清空内容,同时处理游戏胜利后的DOM恢复

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 03:29:55