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

如何更新变量使其可以在其他作用域中正常使用

问题根源说明

你遇到的现象并非作用域问题:全局声明的let second = 20可以在定时器回调中正常修改,全局环境下也能访问到修改后的值。核心问题是代码执行顺序:
外层的if (second > 0)判断是脚本加载后同步执行的,此时定时器回调还没触发过,second仍然是初始值20,且这个判断只会执行一次,后续second递减到0时也不会重新触发判断、禁用已绑定的点击逻辑。

解决方案

推荐两种实现方式,按需选择:

方案1:点击时判断投票状态(改动最小)

直接移除外层的if (second > 0)判断,把有效性校验放到点击事件回调内部,每次点击时先检查当前second值,投票已结束就直接终止逻辑执行:

votingEnd = document.querySelector(".imposters__voting");
imposters = document.querySelectorAll(".imposter");
let second = 20;

window.addEventListener("load", function () {
  let myinterval;

  myinterval = setInterval(function () {
    second--;

    if (second < 11) {
      votingEnd.style.color = "red";
    }

    votingEnd.innerHTML = `Voting ends in: ${second}s`;
    if (second == 0) {
      clearInterval(myinterval);
      votingEnd.innerHTML = `Voting has ended`;
    }
  }, 1000);
});

// 直接绑定点击事件,不在外层做一次性判断
for (let i = 0; i < imposters.length; i++) {
  imposters[i].addEventListener("click", function () {
    // 每次点击都判断投票是否结束,结束就直接返回不执行后续逻辑
    if (second <= 0) return;
    let count = 0;
    while (count < imposters.length) {
      imposters[count++].classList.remove("voted");
    }
    this.classList.add("voted");
  });
}

方案2:投票结束后直接移除所有点击监听

如果需要彻底禁用事件、避免每次点击都做判断,可以把点击监听函数抽成公共变量,等倒计时归0时遍历移除所有元素的点击监听:

votingEnd = document.querySelector(".imposters__voting");
imposters = document.querySelectorAll(".imposter");
let second = 20;

// 抽离点击监听函数,方便后续移除
function handleImposterClick() {
  let count = 0;
  while (count < imposters.length) {
    imposters[count++].classList.remove("voted");
  }
  this.classList.add("voted");
}

window.addEventListener("load", function () {
  let myinterval;

  myinterval = setInterval(function () {
    second--;

    if (second < 11) {
      votingEnd.style.color = "red";
    }

    votingEnd.innerHTML = `Voting ends in: ${second}s`;
    if (second == 0) {
      clearInterval(myinterval);
      votingEnd.innerHTML = `Voting has ended`;
      // 投票结束后遍历移除所有点击监听
      for (let i = 0; i < imposters.length; i++) {
        imposters[i].removeEventListener("click", handleImposterClick);
      }
    }
  }, 1000);
});

// 页面初始化时直接绑定点击事件
for (let i = 0; i < imposters.length; i++) {
  imposters[i].addEventListener("click", handleImposterClick);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 06:27:03