颜色匹配游戏重置后两段setTimeout代码未执行的问题求助
问题分析与解决方案
我帮你定位到问题啦!核心问题在于那两个控制颜色询问弹窗的setTimeout——它们现在处于全局作用域,只会在页面首次加载时执行一次。当你完成第一轮猜测调用initialize()重置游戏时,这两个定时器并不会重新触发,所以第二轮及之后就再也看不到颜色询问的弹窗了。
修复步骤
我们需要把弹窗触发逻辑封装成可复用的函数,并且在每次调用initialize()时重新执行这个逻辑,同时还要处理定时器重复叠加的问题。
1. 添加定时器ID变量
首先在全局作用域添加两个变量,用来存储定时器的ID,方便后续清除旧的定时器,避免多个定时器同时运行:
let colors = ["red", "yellow", "blue", "green", "orange", "purple"], $fullbox = $('.container'), $popup = $('.question'), gamecolor = [], $restart = $('#btn'), clicks = 0, guessColor = [], score = 0, guess, promptTimer1, // 存储第一个弹窗定时器ID promptTimer2; // 存储第二个弹窗定时器ID
2. 封装弹窗触发函数
创建一个专门的函数来处理弹窗的显示与隐藏逻辑,每次调用时先清除旧的定时器,再创建新的:
function startGuessPrompt() { // 清除之前的定时器,防止重复触发 clearTimeout(promptTimer1); clearTimeout(promptTimer2); promptTimer1 = setTimeout(() => { $popup.css('display', 'flex'); guessColor = colors[Math.floor(Math.random() * colors.length)]; // 先移除之前的颜色文本,避免重复添加 $('.questionbox').find('span').remove(); $('.questionbox').find('p').after(`<span> ${guessColor}?</span>`); }, 2500); promptTimer2 = setTimeout(() => { $popup.css('display', 'none'); $('body').css("pointer-events", "auto"); }, 6000); }
3. 在initialize()中调用弹窗函数
修改initialize()函数,在末尾调用startGuessPrompt(),这样每次重置游戏都会重新触发弹窗逻辑:
function initialize () { clicks = 0; $('.colorbox').removeClass('border'); $('.colorbox').removeClass('border-red'); $('.colorbox').each(function () { $('body').css("pointer-events", "none"); $('.colorbox').removeClass('hide'); $(this).css("border", "2px solid black"); let randColor = colors[Math.floor(Math.random() * colors.length)]; $(this).css("background-color", `${randColor}`); setTimeout(hide, 3000); }); // 调用弹窗触发函数 startGuessPrompt(); }
4. 移除全局作用域的旧定时器代码
删除原来写在全局的两个setTimeout,因为现在已经把逻辑移到了startGuessPrompt()函数里。
额外优化点
另外,你原来的window.onload写法有个小问题:
window.onload = initialize(); // 这里会立即执行initialize,而不是等页面加载完成
应该改成:
window.onload = initialize; // 赋值函数引用,页面加载完成后自动执行
完整修改后的JavaScript代码
let colors = ["red", "yellow", "blue", "green", "orange", "purple"], $fullbox = $('.container'), $popup = $('.question'), gamecolor = [], $restart = $('#btn'), clicks = 0, guessColor = [], score = 0, guess, promptTimer1, promptTimer2; window.onload = initialize; // initialize board function initialize () { clicks = 0; $('.colorbox').removeClass('border'); $('.colorbox').removeClass('border-red'); $('.colorbox').each(function () { $('body').css("pointer-events", "none"); $('.colorbox').removeClass('hide'); $(this).css("border", "2px solid black"); let randColor = colors[Math.floor(Math.random() * colors.length)]; $(this).css("background-color", `${randColor}`); setTimeout(hide, 3000); }); startGuessPrompt(); } function hide() { $('.colorbox').each(function () { $(this).addClass('hide'); $('body').css("pointer-events", "auto"); $('.colorbox').css("pointer-events", "auto"); }); } // 封装弹窗触发逻辑 function startGuessPrompt() { clearTimeout(promptTimer1); clearTimeout(promptTimer2); promptTimer1 = setTimeout(() => { $popup.css('display', 'flex'); guessColor = colors[Math.floor(Math.random() * colors.length)]; $('.questionbox').find('span').remove(); $('.questionbox').find('p').after(`<span> ${guessColor}?</span>`); }, 2500); promptTimer2 = setTimeout(() => { $popup.css('display', 'none'); $('body').css("pointer-events", "auto"); }, 6000); } //restart $('#btn').on('click', () => { initialize(); }) $('.container').on('click', '.colorbox', function () { console.log($(this)); $(this).css("pointer-events", "none"); clicks++; guess = $(this)[0].style.backgroundColor; console.log(guess); $(this).removeClass('hide'); console.log(guessColor); console.log(guess); if (guess === guessColor) { score++; $('#score').html(score); $(this).addClass('border'); } else { $(this).addClass('border-red'); } if (clicks >= colors.length) { setTimeout(initialize, 800); $('body').css("pointer-events", "none"); } console.log($(this)); });
这样修改后,每次调用initialize()重置游戏时,都会重新触发颜色询问的弹窗逻辑,完美解决你遇到的问题~
内容的提问来源于stack exchange,提问作者Brian
相关产品推荐
相关产品推荐

