jQuery中setTimeout仅初始点击生效,后续失效(记忆游戏场景)
解决记忆游戏中setTimeout失效的问题
嘿,我帮你揪出这个问题的根源啦!
你遇到的核心问题是**cardFlip = 0的重置时机不对**,再加上匹配成功时的计数重置逻辑缺失,导致后续的setTimeout触发异常:
- 目前你把
cardFlip = 0写在了setTimeout外面,这会导致卡片还在延迟复原的过程中(800ms还没到),计数就已经被重置为0。如果这时候用户不小心点击了卡片(虽然你设置了pointerEvents: none,但万一匹配后的逻辑里没有维持这个限制),就会打乱计数节奏。 - 更关键的是,当两张卡片匹配成功时,你的代码里应该没有重置
cardFlip为0,导致下一轮点击时,计数是从之前的数值(比如2)开始累加,自然不会触发cardFlip == 2的判断,也就不会执行setTimeout的复原逻辑——直到你点击第三张卡片,计数达到某个临界值才会触发(这就是你看到的“点击第三张才恢复”的原因)。
修复方案
1. 调整cardFlip的重置位置
把cardFlip = 0移到setTimeout的回调函数内部,确保只有当卡片完全复原后,才重置计数,避免提前重置导致的混乱:
else if (cardFlip == 2) { $box.css("pointerEvents", "none"); setTimeout(() => { $(".active").removeClass("active"); $(".first").removeClass("first"); $(".second").removeClass("second"); $box.css("pointerEvents", "all"); cardFlip = 0; // 移到这里,卡片复原后再重置计数 }, 800); // 删掉原来这里的cardFlip = 0 }
2. 匹配成功时也要重置计数
在你的卡片匹配判断逻辑里,一定要记得重置cardFlip,保证下一轮点击从0开始:
// 假设这是你判断卡片匹配的逻辑 if (当前两张卡片匹配) { // 比如给匹配的卡片加个标记,避免再次点击 $(".active").addClass("matched"); cardFlip = 0; // 重置计数 $box.css("pointerEvents", "all"); // 如果之前禁用了点击,这里恢复 }
3. 额外优化:避免无效点击干扰
给已匹配的卡片添加过滤逻辑,防止用户点击已匹配的卡片打乱计数:
$box.on("click", function() { // 如果是已匹配的卡片,直接跳过,不增加计数 if ($(this).hasClass("matched")) return; cardFlip++; // 你的其他翻转逻辑... });
还可以加一个状态变量,标记当前是否正在处理卡片复原,双重防止用户重复点击:
let isProcessing = false; $box.on("click", function() { if (isProcessing || $(this).hasClass("matched")) return; cardFlip++; // 其他逻辑... }); // 在处理不匹配的逻辑里使用这个状态 else if (cardFlip == 2) { isProcessing = true; $box.css("pointerEvents", "none"); setTimeout(() => { // 复原逻辑... $box.css("pointerEvents", "all"); cardFlip = 0; isProcessing = false; // 处理完成后解锁 }, 800); }
这样调整后,不管是匹配还是不匹配的情况,计数都会被正确重置,setTimeout的延迟复原功能就能正常工作啦!
内容的提问来源于stack exchange,提问作者maxineheadroom
相关产品推荐
相关产品推荐

