这是我的HTML:
<div class="slider_container Centered">
<figure id="Slider">
<img src="Images/HBC.jpg" id="1" class="effect Image"/>
<img src="Images/Easter-Pic.jpg" id="2" class="effect Image"/>
</figure>
</div>
和我的Javascript:
var Figure_Slider;
var Images;
var Image_Num;
var Current_Element;
var Previous_Element;
function main()
{
Figure_Slider = document.getElementById("Slider");
Images = document.getElementById("Slider").children;
Image_Num = Images.length;
for (var i = 1; i <= Image_Num; i++)
{
var index = i;
Current_Element = document.getElementById(i.toString());
if (index == 1)
{
Current_Element.classList.add("active");
}
else
{
Previous_Element.classList.remove("active");
Current_Element.classList.add("active");
}
window.setTimeout(function(){advance();}, 4000); //This doesn't work
advance();
}
Current_Element.classList.remove("active");
}
function advance()
{
Previous_Element = Current_Element;
}
window.onload = main;
我正在尝试制作图片滑块。当我使用Chrome调试工具,并手动单步执行javascript时,它可以正常工作。当我直接运行时,不执行计时器。 setTimeout
函数有什么问题?我已经看到很多关于它的输出没有给变量的例子,所以不是这样。我甚至做了匿名功能修复。 advance();
下面的setTimeout
调用只是暂时的,所以我可以查看逻辑。如果没有advance();
行,脚本将删除未处理的事件,其中Previous_Element
没有名为active的类要删除。因此,定时器语句的两个部分(延迟和函数执行)都不会发生。除此之外,代码工作正常。如果您需要CSS,请告诉我。我尝试了一些修复:
function wait(delay)
{
setInterval(advance(), delay);
}
然后在循环中调用该函数,但它使用100%或更多的CPU来锁定浏览器。还有另一种方法吗?
提前致谢。
答案 0 :(得分:1)
请将您的setTimeout函数包装在IIFE的闭包中。
for (var i = 1; i <= 3; i++)
{
(function(idx)
{
setTimeout(function() { alert(idx); }, i * 500);
})(i);
}
希望它会对你有所帮助。
答案 1 :(得分:0)
循环/迭代本质上是阻塞的,而setTimeout本质上是异步/解除阻塞。 放置在for循环中时,SetTimeout不起作用, 这样可以正常工作!
function wait(fn) {
window.setTimeout(function() { fn(); }, 1000);
}
for (var i = 1; i <=5; ++i){
/* ... */
wait(advance);
/* ... */
}
如果你想使用setTimeout等待一段时间再执行,你可以使用它(如果是的话,你应该在问题中提到它)
function blockUntil(fn,delay){
var until = new Date().getTime() + delay;
while(new Date().getTime() < until) {};
fn();
}
for (var i = 0; i < 5; i++) {
blockUntil(advance,1000);
};
答案 2 :(得分:0)
部分问题是setTimeout()函数被调用两次,但它们几乎在同一时间被调用。 for循环几乎没有时间在两个图像列表中迭代两次,因此几乎在同一时间调用setTimeout()。这使它看起来只被调用一次。尝试在setTimeout之前的行中放入console.log,然后在setTimeout中放入另一个控制台日志 - 它将帮助显示何时发生。这个问题/答案也很好地解释了它:setTimeout in for-loop does not print consecutive values
答案 3 :(得分:0)
它按预期工作。请查看我的小提琴演示https://jsfiddle.net/jrsucfc4/1
function advance(param) {
advanceCallCount++;
console.log('advanceCallCount = ' + advanceCallCount+ '; advance param: ' + param);
Previous_Element = Current_Element;
}
另一件事是你期望得到这个执行的结果?
答案 4 :(得分:0)
事实证明,文档忘记提及setTimout
和setInterval
的工作原理。当执行到达此命令时,它会启动计时器,并使用代码 CONTINUES 。计时器完成后,那么执行内部功能。在执行内部功能之前,程序不会暂停。我的逻辑已被更改,因此我使用了setInterval
,这是我的main函数的最后一行代码。 setTimout
和setInterval
的文档应包含此重要信息。这是我的主要现在的样子
function main()
{
Figure_Slider = document.getElementById("Slider");
Images = document.getElementById("Slider").children;
Caption = document.getElementById("Caption");
Image_Num = Images.length;
Image_Counter = 1;
Current_Element = document.getElementById(Image_Counter.toString());
Current_Element.classList.add("active");
Caption.innerHTML = Current_Element.alt;
window.setInterval(function (){image_slider();}, 5000);
}
无论如何,谢谢你的帮助。