Javascript setTimeout未执行

时间:2016-03-20 05:21:08

标签: javascript

这是我的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来锁定浏览器。还有另一种方法吗?

提前致谢。

5 个答案:

答案 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)

事实证明,文档忘记提及setTimoutsetInterval的工作原理。当执行到达此命令时,它会启动计时器,并使用代码 CONTINUES 。计时器完成后,那么执行内部功能。在执行内部功能之前,程序不会暂停。我的逻辑已被更改,因此我使用了setInterval,这是我的main函数的最后一行代码。 setTimoutsetInterval的文档应包含此重要信息。这是我的主要现在的样子

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

无论如何,谢谢你的帮助。