我必须每秒更改图像的来源。我有一个for循环,其中调用一个具有超时的函数。我在这里读取了stackOverflow,但它不起作用。可以请有人告诉我,我可以修复什么使其工作?我一直在努力解决这个问题,我想承认。感谢。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script type="text/javascript">
function changeImage(k) {
setTimeout(function(){
document.getElementById("img").src = k + ".png"; alert(k );}, 1000);
}
function test() {
for (var k = 1; k <= 3; k++) {
changeImage(k);
}
}
</script>
</head>
<body>
<div id="main_img">
<img id="img" src="http://placehold.it/110x110">
</div>
<input type="button" style="width: 200px" onclick="test()" />
</body>
答案 0 :(得分:5)
在您的代码中,您可以立即设置所有超时。因此,如果你从现在开始设置 all 一秒钟,那么 all 从现在开始一秒钟。
您已经在索引k
中传递,因此只需将时间参数乘以k
。
setTimeout(function(){
document.getElementById("img").src = k + ".png";
alert(k);
}, k * 1000);
// ^ added
答案 1 :(得分:2)
问题是你要创建一个间隔毫秒的实例。一秒钟后,它们也会分开几毫秒。你需要的是以彼此相隔的设定间隔执行它们。
您可以使用setInterval
使用计时器,它以给定的间隔执行提供的功能。不要忘记杀掉计时器,否则它会永远运行。
您可以将元素缓存在变量中,这样您就不会经常访问DOM。
另外,我会避开alert()
。如果要调试,请在调试器中使用断点。如果您真的希望它像“类似警报”,请使用console.log
并观看控制台。
setInterval
相对于递归setTimeout
的一个优点是,每次迭代不会产生多个计时器,而只会产生一个计时器。
以下是建议的解决方案:
var k = 0;
var image = document.getElementById("img");
var interval = setInterval(function() {
// Increment or clear when finished. Otherwise, you'll leave the timer running.
if(k++ < 3) clearInterval(interval);
image.src = k + ".png";
// Execute block every 1000ms (1 second)
},1000);
答案 2 :(得分:1)
您可以这样做,而不是使用循环:
var k = 0;
var int = setInterval(function() {
if (k <= 3) k++;
else { clearInterval(int); }
document.getElementById("img").src = k + ".png";
alert(k);
}, 1000);
答案 3 :(得分:1)
setTimeout不会停止程序执行,只会在1秒内为回调设置一个事件。这意味着如果你在for循环中设置了三个setTimeout,它们将在1秒后同时执行。
您可以使用延迟递归,而不是使用for循环。
function changeImage(imageIndex) {
document.getElementById("img").src = imageIndex + ".png";
alert(imageIndex);
}
function myLoop( imageIndex ) {
if( imageIndex >= 3 ) return;
changeImage( imageIndex );
setTimeut( function() { myLoop(imageIndex + 1) }, 1000 );
}
setTimeut( function() { myLoop(0) }, 1000 );
var interval = null;
var imageIndex = 0;
function changeImage() {
document.getElementById("img").src = imageIndex + ".png";
alert(imageIndex);
imageIndex++;
if( imageIndex === 3 ) clearInterval( interval );
}
interval = setInterval( changeImage , 1000);
function changeImage(imageIndex) {
document.getElementById("img").src = imageIndex + ".png";
alert(imageIndex);
}
for( var i=0; i < 3; i++) {
setTimeout( changeImage.bind(window, i), i * 1000 );
}
(function f(i) { setTimeout( changeImage(i) || f.bind(window, i = (i++)%3), 1000); })(0)
答案 4 :(得分:1)
我的建议是使用console.log()或alert()来帮助您进行调试 - 这将使得它变得更加明显正在发生的事情。例如,如果你在test或setTimeout函数中放置了console.log,你会发现所有三个图像都是同时添加的。
我建议的是声明你的“nextImage”函数,然后在该函数中定义你的setTimeout。这样它每秒都会自称。
另一个提示:我假设您希望这三个图像永远循环,所以我添加了一个常用的技巧和模数运算符(%)来完成此任务。
看看:
工作演示:http://jsfiddle.net/franksvalli/PL63J/2/
(function(){
var numImages = 3, // total count of images
curImage = 1, // start with image 1
$image = document.getElementById("img"),
imageBase = "http://placehold.it/110x11";
function nextImage() {
$image.src = imageBase + curImage;
// increment by one, but loop back to 1 if the count exceeds numImages
curImage = (curImage % numImages) + 1;
// execute nextImage again in roughly 1 second
window.setTimeout(nextImage, 1000);
}
// initializer. Hook this into a click event if you need to
nextImage();
})();
正如其他人所说,你可能想要使用setInterval,你可以通过一些调整来做:
(function(){
var numImages = 3, // total count of images
curImage = 1, // start with image 1
$image = document.getElementById("img"),
imageBase = "http://placehold.it/110x11";
function nextImage() {
$image.src = imageBase + curImage;
// increment by one, but loop back to 1 if the count exceeds numImages
curImage = (curImage % numImages) + 1;
}
// initializer. Hook this into a click event if you need to
nextImage(); // call function immediately without delay
window.setInterval(nextImage, 1000);
})();
答案 5 :(得分:1)
为什么它不起作用?
因为Javascript总是通过引用传递变量。当您的代码在队列中等待时,变量已经更改。
我的解决方案:
创建一个数组并按照出现的顺序推送你想要执行的任何代码(直接放置变量的实际值),例如:
var launcher = [];
launcher.push('alert("First line of code with variable '+ x +'")');
launcher.push('alert("Second line of code with variable '+ y +'")');
launcher.push('alert("Third line of code with variable '+ z +'")');
使用setInterval而不是setTimeout来执行代码(您甚至可以动态更改延迟时间),例如。
var loop = launcher.length;
var i = 0;
var i1 = setInterval(function(){
eval(launcher[count]);
count++;
if(i >= loop) {
clearInterval(i1);
}
}, 20);