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

颜色匹配游戏重置后两段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>&nbsp; ${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>&nbsp; ${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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 22:38:12