如何更新变量以在另一个范围内使用

How to update a variable to use in another scope

我有一个变量 let second = 20,我降低 1 直到它达到 0。当它达到 0 时,我想停止 运行 我的代码的一部分,但是变量 second 总是 20,当我使用它是因为我在另一个范围内降低了它。对不起,如果我的解释有点不清楚。

代码如下:

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);
});

if (second > 0) {
  //second is still 20 here because i lowered it in my function above. How can i solve this
  for (let i = 0; i < imposters.length; i++) {
    imposters[i].addEventListener("click", function () {
      let count = 0;
      while (count < imposters.length) {
        imposters[count++].classList.remove("voted");
      }
      this.classList.add("voted");
    });
  }
}

您的 setInterval 每秒运行一次。这并不意味着其余代码也每秒运行一次。这就是为什么当代码到达 if (second > 0).

时秒仍然是 20

所以您需要确保您的这部分代码也每秒运行一次。一种解决方案是将该代码包装在您在间隔内调用的函数中,如下所示:

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`;
    }
    check();
  }, 1000);
});

function check() {
if (second > 0) {
  //second is still 20 here because i lowered it in my function above. How can i solve this
  for (let i = 0; i < imposters.length; i++) {
    imposters[i].addEventListener("click", function () {
      let count = 0;
      while (count < imposters.length) {
        imposters[count++].classList.remove("voted");
      }
      this.classList.add("voted");
    });
  }
}
}

问题与作用域无关。这与时间有关。你的代码的最后一部分只有 运行s 一次,在间隔 运行s 二十次之前。

操作顺序如下:

  1. second初始化为20
  2. 将倒计时功能绑定到window.onload。 (这还 运行)
  3. 检查seconds是否大于0,这是因为区间还没有运行。这是此代码 唯一曾经 运行s.
  4. window.onload被触发,您的倒计时开始
  5. 一秒后,seconds 现在是 19
  6. 19秒后seconds不是0,间隔清空

所以您需要做的是在间隔.

的每次迭代中触发您的代码

你想要更接近于:

let second = 20;

window.addEventListener("load", function () {
  const myinterval = setInterval(function () {
    second--;

    // other logic here...

    if (second > 0) {
      countdownTick(); // runs every second with the interval handler
    }

    if (second == 0) {
      clearInterval(myinterval);
      // cleanup
    }
  }, 1000);
});

function countdownTick() {
  // Do the stuff you need to do each second here
}

您可以将 if (second > 0) 放在 click 函数中,这样它将检查 second 的最新值,而不是像这样在加载时只检查一次

for(let i = 0; i < imposters.length; i++){
    imposters[i].addEventListener("click", function () {
        if (second > 0) {
        let count = 0;
            while (count < imposters.length) {
                imposters[count++].classList.remove("voted");
                    }
            this.classList.add("voted");
        }
    });