JavaScript - setInterval 函数:间隔不会清除
JavaScript - setInterval function: interval won't clear
注意:我查看了所有与 setInterval / clearInterval 相关的问题和答案,其中 none 有任何帮助。不要将其标记为重复项。
我有一个 HTML 页面,其中的一个元素的背景颜色会发生变化(从红色到绿色再到蓝色等等)。单击时,颜色应停止变化。我正在使用 setInterval 来 运行 一个 updateCard() 函数,该函数应该检查颜色当前是否正在更改并清除间隔或重置它。单击时,它不会停止更改颜色。我添加了 console.log 检查以查看间隔 ID 是否正在更改,我发现它是(我的函数称为更新)所以我修复了它。间隔 ID 现在在清除时与定义时相同。这是我的 colorChange.js 文件,它嵌入在我的 HTML.
中
var titleCard = document.getElementById("titleCard"),
red = 255,
green = 255,
blue = 255,
redDir = 1,
greenDir = -1,
blueDir = -1,
on = true,
colorChange = setInterval(updateCard, 10);
function updateCard() {
if (red > 255) red = 255;
if (green > 255) green = 255;
if (blue > 255) blue = 255;
if (red < 0) red = 0;
if (green < 0) green = 0;
if (blue < 0) blue = 0;
red += redDir;
green += greenDir;
blue += blueDir;
if (red >= 255 && green <= 0 && blue <= 0) turnGreen();
if (red <= 0 && green >= 255 && blue <= 0) turnBlue();
if (red <= 0 && green <= 0 && blue >= 255) turnRed();
titleCard.style.backgroundColor = "rgb(" + red + "," + green + "," + blue + ")";
}
function turnRed() {
redDir = 1;
greenDir = -1;
blueDir = -1;
}
function turnGreen() {
redDir = -1;
greenDir = 1;
blueDir = -1;
}
function turnBlue() {
redDir = -1;
greenDir = -1;
blueDir = 1;
}
titleCard.onclick = function() {
if (on) {
console.log("Clearing: " + colorChange);
clearInterval(colorChange);
on = false;
} else {
colorChange = setInterval(updateCard, 10);
console.log("Set: " + colorChange);
on = true;
}
}
<!DOCTYPE HTML>
<html>
<head>
<title>My Website</title>
<link rel="shortcut icon" type="image/x-icon" href="images/favicon.ico"/>
<link rel="apple-touch-icon" href="images/apple_icon.png"/>
<link rel="apple-touch-icon-precomposed" href="images/apple_icon.png"/>
<link rel="stylesheet" href="/css/materialize.min.css"/>
<link rel="stylesheet" href="/css/style.css"/>
</head>
<body>
<div class="container">
<div class="card hoverable">
<h1 id="titleCard" class="card-content center">My Name</h1>
</div>
</div>
<div class="row">
<div class="col s4 push-s4">
<div id="welcomeCard" class="card teal lighten-3">
<p class="card-content center">Welcome to my website.<br/>Enjoy your stay.</p>
</div>
</div>
</div>
<div id="background1"></div>
</body>
<script src="/js/colorChange.js"></script>
<script src="/js/changeTitle.js"></script>
<script src="/js/style.js"></script>
</html>
这是我控制台中元素被点击 5 次的示例:
colorChange.js:50 Clearing: 61
colorChange.js:55 Set: 62
colorChange.js:50 Clearing: 62
colorChange.js:55 Set: 63
colorChange.js:50 Clearing: 63
这证明 clearInterval 调用正在清除正确的 ID。为什么颜色还在变?
编辑:
好笑的是,上面的代码片段实际上运行正常。然而,在我的网页中,它没有。我比以前更糊涂了。
编辑 2:我添加了完整的 HTML 页面。
编辑 3:
这是我的其他 JS 文件,可能那里有问题?
changeTitle.js
var titleCard = document.getElementById("titleCard");
currentTime = new Date().getHours() + ":" + new Date().getMinutes(),
today = new Date().getMonth() + 1 + "/" + new Date().getDate(),
colorChange = setInterval(updateCard, 10);
function updateCard() {
currentTime = new Date().getHours() + ":" + new Date().getMinutes();
if (currentTime == "11:11" || currentTime == "23:11") changeTitle("Make a wish!", 1);
else if (today == "2/13") changeTitle("Happy birthday to me", 1);
else if (today == "12/11") changeTitle("Happy birthday, Kayla!", 1);
else if (today == "3/7") changeTitle("Happy birthday, Nathan!", 1);
else if (today == "1/1") changeTitle("Happy birthday, Mom!", 1);
else if (today == "1/29") changeTitle("Happy birthday, Dad!", 1);
else if (today == "8/3") changeTitle("Happy birthday, Brandon!", 1);
else if (today == "7/24") changeTitle("Happy birthday, Dustin!", 1);
else if (today == "11/23") changeTitle("Happy birthday, Branson!", 1);
else if (today == "11/8") changeTitle("Happy birthday, Jack!", 1);
else defaultTitle();
}
function changeTitle(body, interval) {
titleCard.innerHTML = body;
clearInterval(colorChange);
colorChange = setInterval(updateCard, interval);
}
function defaultTitle() {
titleCard.innerHTML = "MY NAME";
clearInterval(colorChange);
colorChange = setInterval(updateCard, 10);
}
style.js
var background1 = document.getElementById("background1");
background1.style.position = "absolute";
background1.style.backgroundColor = "black";
background1.style.top = 0;
background1.style.left = 0;
background1.style.width = "100%";
background1.style.height = "25%";
background1.style.zIndex = -1;
我快要死了
最终编辑:已解决,查看@GregL 和@CodeiSir 的答案。
我完成了代码,
这是一个有效的例子:(按 运行)(如果你想知道,当鼠标按钮在它按下的同一个对象上上升时,onclick
被触发,所以你可能没有即时反应,使用 onmousedown
来查看即时反应)
var titleCard = document.getElementById("titleCard"),
red = 255,
green = 255,
blue = 255,
redDir = 1,
greenDir = -1,
blueDir = -1,
on = true,
colorChange = setInterval(updateCard, 10);
function updateCard() {
if (red > 255) red = 255;
if (green > 255) green = 255;
if (blue > 255) blue = 255;
if (red < 0) red = 0;
if (green < 0) green = 0;
if (blue < 0) blue = 0;
red += redDir;
green += greenDir;
blue += blueDir;
if (red >= 255 && green <= 0 && blue <= 0) turnGreen();
if (red <= 0 && green >= 255 && blue <= 0) turnBlue();
if (red <= 0 && green <= 0 && blue >= 255) turnRed();
titleCard.style.backgroundColor = "rgb(" + red + "," + green + "," + blue + ")";
}
function turnRed() {
redDir = 1;
greenDir = -1;
blueDir = -1;
}
function turnGreen() {
redDir = -1;
greenDir = 1;
blueDir = -1;
}
function turnBlue() {
redDir = -1;
greenDir = -1;
blueDir = 1;
}
titleCard.onclick = function() {
if (on) {
console.log("Clearing: " + colorChange);
clearInterval(colorChange);
on = false;
} else {
colorChange = setInterval(updateCard, 10);
console.log("Set: " + colorChange);
on = true;
}
}
<div id="titleCard" style="height: 100px; width: 100px"></div>
编辑:
这是问题所在:
您再次在 changeTitle.js
中使用相同的变量:
var titleCard = document.getElementById("titleCard");
currentTime = new Date().getHours() + ":" + new Date().getMinutes(),
today = new Date().getMonth() + 1 + "/" + new Date().getDate(),
colorChange = setInterval(updateCard, 10);
您将不得不为您的每个文件使用不同的变量
问题是你在多个JS文件中重新定义了一些关键变量和函数,所以后面的值会覆盖前面的值,导致原来的值变成"lost".
这是因为在 Javascript 中,只有函数会创建一个新的作用域,因此任何 JS 文件中函数之外的内容都将位于全局命名空间中。
但是,您可以使用一种称为 IIFE(通常发音为 "iffy")的技术来利用函数创建新命名范围的事实,从而将每个代码文件彼此隔离,并允许一切正常工作。
这里有一个 forked Plunkr 可以正常工作。
核心更改是将此行添加到两个 JS 文件的顶部:
(function () {
每个 JS 文件底部的这一行:
})();
编辑:归功于@CodeiSir,他发现问题是两个 JS 文件中变量和函数名称的重用。
注意:我查看了所有与 setInterval / clearInterval 相关的问题和答案,其中 none 有任何帮助。不要将其标记为重复项。
我有一个 HTML 页面,其中的一个元素的背景颜色会发生变化(从红色到绿色再到蓝色等等)。单击时,颜色应停止变化。我正在使用 setInterval 来 运行 一个 updateCard() 函数,该函数应该检查颜色当前是否正在更改并清除间隔或重置它。单击时,它不会停止更改颜色。我添加了 console.log 检查以查看间隔 ID 是否正在更改,我发现它是(我的函数称为更新)所以我修复了它。间隔 ID 现在在清除时与定义时相同。这是我的 colorChange.js 文件,它嵌入在我的 HTML.
中var titleCard = document.getElementById("titleCard"),
red = 255,
green = 255,
blue = 255,
redDir = 1,
greenDir = -1,
blueDir = -1,
on = true,
colorChange = setInterval(updateCard, 10);
function updateCard() {
if (red > 255) red = 255;
if (green > 255) green = 255;
if (blue > 255) blue = 255;
if (red < 0) red = 0;
if (green < 0) green = 0;
if (blue < 0) blue = 0;
red += redDir;
green += greenDir;
blue += blueDir;
if (red >= 255 && green <= 0 && blue <= 0) turnGreen();
if (red <= 0 && green >= 255 && blue <= 0) turnBlue();
if (red <= 0 && green <= 0 && blue >= 255) turnRed();
titleCard.style.backgroundColor = "rgb(" + red + "," + green + "," + blue + ")";
}
function turnRed() {
redDir = 1;
greenDir = -1;
blueDir = -1;
}
function turnGreen() {
redDir = -1;
greenDir = 1;
blueDir = -1;
}
function turnBlue() {
redDir = -1;
greenDir = -1;
blueDir = 1;
}
titleCard.onclick = function() {
if (on) {
console.log("Clearing: " + colorChange);
clearInterval(colorChange);
on = false;
} else {
colorChange = setInterval(updateCard, 10);
console.log("Set: " + colorChange);
on = true;
}
}
<!DOCTYPE HTML>
<html>
<head>
<title>My Website</title>
<link rel="shortcut icon" type="image/x-icon" href="images/favicon.ico"/>
<link rel="apple-touch-icon" href="images/apple_icon.png"/>
<link rel="apple-touch-icon-precomposed" href="images/apple_icon.png"/>
<link rel="stylesheet" href="/css/materialize.min.css"/>
<link rel="stylesheet" href="/css/style.css"/>
</head>
<body>
<div class="container">
<div class="card hoverable">
<h1 id="titleCard" class="card-content center">My Name</h1>
</div>
</div>
<div class="row">
<div class="col s4 push-s4">
<div id="welcomeCard" class="card teal lighten-3">
<p class="card-content center">Welcome to my website.<br/>Enjoy your stay.</p>
</div>
</div>
</div>
<div id="background1"></div>
</body>
<script src="/js/colorChange.js"></script>
<script src="/js/changeTitle.js"></script>
<script src="/js/style.js"></script>
</html>
这是我控制台中元素被点击 5 次的示例:
colorChange.js:50 Clearing: 61
colorChange.js:55 Set: 62
colorChange.js:50 Clearing: 62
colorChange.js:55 Set: 63
colorChange.js:50 Clearing: 63
这证明 clearInterval 调用正在清除正确的 ID。为什么颜色还在变?
编辑: 好笑的是,上面的代码片段实际上运行正常。然而,在我的网页中,它没有。我比以前更糊涂了。
编辑 2:我添加了完整的 HTML 页面。
编辑 3: 这是我的其他 JS 文件,可能那里有问题?
changeTitle.js
var titleCard = document.getElementById("titleCard");
currentTime = new Date().getHours() + ":" + new Date().getMinutes(),
today = new Date().getMonth() + 1 + "/" + new Date().getDate(),
colorChange = setInterval(updateCard, 10);
function updateCard() {
currentTime = new Date().getHours() + ":" + new Date().getMinutes();
if (currentTime == "11:11" || currentTime == "23:11") changeTitle("Make a wish!", 1);
else if (today == "2/13") changeTitle("Happy birthday to me", 1);
else if (today == "12/11") changeTitle("Happy birthday, Kayla!", 1);
else if (today == "3/7") changeTitle("Happy birthday, Nathan!", 1);
else if (today == "1/1") changeTitle("Happy birthday, Mom!", 1);
else if (today == "1/29") changeTitle("Happy birthday, Dad!", 1);
else if (today == "8/3") changeTitle("Happy birthday, Brandon!", 1);
else if (today == "7/24") changeTitle("Happy birthday, Dustin!", 1);
else if (today == "11/23") changeTitle("Happy birthday, Branson!", 1);
else if (today == "11/8") changeTitle("Happy birthday, Jack!", 1);
else defaultTitle();
}
function changeTitle(body, interval) {
titleCard.innerHTML = body;
clearInterval(colorChange);
colorChange = setInterval(updateCard, interval);
}
function defaultTitle() {
titleCard.innerHTML = "MY NAME";
clearInterval(colorChange);
colorChange = setInterval(updateCard, 10);
}
style.js
var background1 = document.getElementById("background1");
background1.style.position = "absolute";
background1.style.backgroundColor = "black";
background1.style.top = 0;
background1.style.left = 0;
background1.style.width = "100%";
background1.style.height = "25%";
background1.style.zIndex = -1;
我快要死了
最终编辑:已解决,查看@GregL 和@CodeiSir 的答案。
我完成了代码,
这是一个有效的例子:(按 运行)(如果你想知道,当鼠标按钮在它按下的同一个对象上上升时,onclick
被触发,所以你可能没有即时反应,使用 onmousedown
来查看即时反应)
var titleCard = document.getElementById("titleCard"),
red = 255,
green = 255,
blue = 255,
redDir = 1,
greenDir = -1,
blueDir = -1,
on = true,
colorChange = setInterval(updateCard, 10);
function updateCard() {
if (red > 255) red = 255;
if (green > 255) green = 255;
if (blue > 255) blue = 255;
if (red < 0) red = 0;
if (green < 0) green = 0;
if (blue < 0) blue = 0;
red += redDir;
green += greenDir;
blue += blueDir;
if (red >= 255 && green <= 0 && blue <= 0) turnGreen();
if (red <= 0 && green >= 255 && blue <= 0) turnBlue();
if (red <= 0 && green <= 0 && blue >= 255) turnRed();
titleCard.style.backgroundColor = "rgb(" + red + "," + green + "," + blue + ")";
}
function turnRed() {
redDir = 1;
greenDir = -1;
blueDir = -1;
}
function turnGreen() {
redDir = -1;
greenDir = 1;
blueDir = -1;
}
function turnBlue() {
redDir = -1;
greenDir = -1;
blueDir = 1;
}
titleCard.onclick = function() {
if (on) {
console.log("Clearing: " + colorChange);
clearInterval(colorChange);
on = false;
} else {
colorChange = setInterval(updateCard, 10);
console.log("Set: " + colorChange);
on = true;
}
}
<div id="titleCard" style="height: 100px; width: 100px"></div>
编辑:
这是问题所在:
您再次在 changeTitle.js
中使用相同的变量:
var titleCard = document.getElementById("titleCard");
currentTime = new Date().getHours() + ":" + new Date().getMinutes(),
today = new Date().getMonth() + 1 + "/" + new Date().getDate(),
colorChange = setInterval(updateCard, 10);
您将不得不为您的每个文件使用不同的变量
问题是你在多个JS文件中重新定义了一些关键变量和函数,所以后面的值会覆盖前面的值,导致原来的值变成"lost".
这是因为在 Javascript 中,只有函数会创建一个新的作用域,因此任何 JS 文件中函数之外的内容都将位于全局命名空间中。
但是,您可以使用一种称为 IIFE(通常发音为 "iffy")的技术来利用函数创建新命名范围的事实,从而将每个代码文件彼此隔离,并允许一切正常工作。
这里有一个 forked Plunkr 可以正常工作。
核心更改是将此行添加到两个 JS 文件的顶部:
(function () {
每个 JS 文件底部的这一行:
})();
编辑:归功于@CodeiSir,他发现问题是两个 JS 文件中变量和函数名称的重用。