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

基于math.random的方块游戏:定时器与点击事件异常问题

问题分析与解决方案

嘿,我来帮你搞定这两个问题,咱们一步步拆解:

问题1:方块无规则乱跳(多实例定时器/重复事件绑定)

你的代码核心问题是重复执行初始化逻辑,导致多个定时器和事件绑定同时运行:

  • 你把test函数作为$(document).ready()的回调,又用setInterval(test, 2000)每隔2秒调用一次test。这意味着每次调用test,都会重新绑定点击事件、创建新的定时器,旧的定时器却没被清理——多个定时器同时触发移动逻辑,方块自然会乱跳。
  • 另外,randPosX和randPosY只在初始化时生成一次,所有移动都会用同一个固定位置,完全不符合"随机位移"的需求。

问题2:第二次点击无响应

点击事件里的clearInterval(fire)无法彻底清理定时器:因为fire是test函数内部的局部变量,每次调用test都会重新创建一个fire,点击时只能清除当前这个fire对应的定时器,之前的定时器还在后台运行,干扰后续的点击逻辑;再加上重复绑定的点击事件,整个逻辑就彻底混乱了。


修复后的完整代码

$(document).ready(function() {
  // 统一管理定时器实例,避免多实例冲突
  var timerId = null;
  var autoMoveTimer = null;
  var timeLeft = 2;
  var elem = document.getElementById('time');
  
  // 封装随机位置生成逻辑,每次移动都生成新位置
  function getRandomPosition() {
    var containerWidth = $("#playArea").width();
    var containerHeight = $("#playArea").height();
    // 用0.9比例限制位置,避免方块超出容器
    return {
      x: Math.floor(Math.random() * (containerWidth * 0.9)),
      y: Math.floor(Math.random() * (containerHeight * 0.9))
    };
  }

  // 封装方块移动逻辑,复用代码
  function moveTarget() {
    var pos = getRandomPosition();
    $('#target').css({
      left: `${pos.x}px`,
      top: `${pos.y}px`
    });
  }

  // 倒计时逻辑
  function countdown() {
    if (timeLeft === 0) {
      moveTarget();
      timeLeft = 5;
    } else {
      elem.innerHTML = `${timeLeft} seconds remaining`;
      timeLeft--;
    }
  }

  // 只绑定一次点击事件,避免重复绑定
  $(document).on('click', '#target', function() {
    moveTarget();
    // 重置倒计时
    timeLeft = 2;
    // 清理并重启倒计时定时器
    if (timerId) clearInterval(timerId);
    timerId = setInterval(countdown, 1000);
    // 清理并重启自动移动定时器
    if (autoMoveTimer) clearInterval(autoMoveTimer);
    autoMoveTimer = setInterval(moveTarget, 2000);
  });

  // 初始化启动定时器
  timerId = setInterval(countdown, 1000);
  autoMoveTimer = setInterval(moveTarget, 2000);
});

关键修复点说明

  • 统一管理定时器:把定时器实例放在ready回调的作用域内,确保每次清理的是同一个定时器,彻底避免多实例冲突。
  • 复用核心逻辑:把生成随机位置和移动方块的逻辑封装成独立函数,每次需要移动时调用,保证每次都是全新的随机位置。
  • 单次事件绑定:点击事件只在页面初始化时绑定一次,避免重复绑定导致的逻辑混乱。
  • 清晰的变量命名:把fire改成autoMoveTimer,让代码可读性更强,减少歧义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:41:50