Javascript setTimeout函数不适用于for循环

Javascript setTimeout函数不适用于for循环,javascript,html,for-loop,slideshow,settimeout,Javascript,Html,For Loop,Slideshow,Settimeout,我试着运行这段代码来制作3张图片的幻灯片,但它不能正常工作。幻灯片放映一次,然后就停止了 下面是我的JavaScript、CSS和HTML,如果您运行代码段,您将看到幻灯片放映一次 HTML基本上是声明一个容器div,其中幻灯片是带有特定背景图像的div。对于这个问题,我将图像更改为颜色,以便您可以看到幻灯片的实际效果 当幻灯片处于普通视图和隐藏状态时,CSS声明每个图像的位置 JavaScript在幻灯片中循环,当幻灯片应该移出视图时,为每个幻灯片提供一个隐藏的类。最后,它通过删除所有隐藏的类

我试着运行这段代码来制作3张图片的幻灯片,但它不能正常工作。幻灯片放映一次,然后就停止了

下面是我的JavaScript、CSS和HTML,如果您运行代码段,您将看到幻灯片放映一次

HTML基本上是声明一个容器div,其中幻灯片是带有特定背景图像的div。对于这个问题,我将图像更改为颜色,以便您可以看到幻灯片的实际效果

当幻灯片处于普通视图和隐藏状态时,CSS声明每个图像的位置

JavaScript在幻灯片中循环,当幻灯片应该移出视图时,为每个幻灯片提供一个隐藏的类。最后,它通过删除所有隐藏的类返回第一张幻灯片

我很确定问题出在带有setTimeout函数的JavaScript中,因为每当我在控制台中运行函数时,它都能完美地工作,但当我尝试自动将它们设置为在JS中运行时,它只运行一次

功能滑块1至2{ document.getElementById'slide1'。className=隐藏; Cleartimeouts1t2; } 功能滑块2至3{ document.getElementById'slide2'。className=隐藏; 清除时间超过2to3; } 功能幻灯片3至1{ document.getElementById'slide1'。className=; document.getElementById'slide2'。className=; 净空时间为3到1; } fori=0;设置超时时,代码不会等待超时完成。这意味着for循环在2秒后执行100次,在4秒后执行100次,在6秒后执行100次

相反,您可以在第三帧结束后重新设置超时

带有超时的简单循环示例:

var i = 0;
function a() {
   //Do some stuff
   if (i++ < 100) setTimeout(a, 1000);
}
这很好。一个坏例子是:

for (var i = 0; i < 100; i++) {
    setTimeout(function() {
        //Do stuff
    }, 1000);
}
第一个将以1秒的间隔执行100次,后一个将执行1次。

设置超时时,代码不会等待超时完成。这意味着for循环在2秒后执行100次,在4秒后执行100次,在6秒后执行100次

相反,您可以在第三帧结束后重新设置超时

带有超时的简单循环示例:

var i = 0;
function a() {
   //Do some stuff
   if (i++ < 100) setTimeout(a, 1000);
}
这很好。一个坏例子是:

for (var i = 0; i < 100; i++) {
    setTimeout(function() {
        //Do stuff
    }, 1000);
}

第一个循环将以1秒的间隔执行100次,后者将执行1次。

正如其他人所提到的,您的循环实际上什么也不做,因为setTimeout是异步的

实现所需结果的一种方法是在每个函数中设置回调函数。然后设置另一个清除超时的功能。要永久循环,只需删除stopTransitions函数及其调用者


正如其他人提到的,由于setTimeout是异步的,所以循环实际上什么都不做

实现所需结果的一种方法是在每个函数中设置回调函数。然后设置另一个清除超时的功能。要永久循环,只需删除stopTransitions函数及其调用者


如果不使用JS和CSS3动画,您可以获得相同的效果。如果代码不完全相同,您应该稍微调整一下时间和样式


如果不使用JS和CSS3动画,您可以获得相同的效果。如果代码不完全相同,您应该稍微调整一下时间和样式


我用这个来工作: 谢谢尤塔姆·萨蒙的回答,这让我明白我做错了什么

我基本上让每个函数设置超时并运行下面的函数,然后让最后一个函数再次运行第一个函数。当时我只需要手动启动第一个,然后它就永远运行下去了

功能滑块1至2{ document.getElementById'slide1'。className=隐藏; setTimeoutslide2to3,4000; } 功能滑块2至3{ document.getElementById'slide2'。className=隐藏; 设置TimeOutslide3到14000; } 功能幻灯片3至1{ document.getElementById'slide1'。className=; document.getElementById'slide2'。className=; setTimeoutslide1to2,4000; } 幻灯片1至2; 幻灯片{ 宽度:100%; 身高:50%; 背景图像:urlwhite-wall.png; } div幻灯片放映div{ 宽度:100%; 身高:继承; 背景重复:无重复; 背景位置:中心; 背景色:rgba0,0,0,0.5; 位置:绝对位置; 过渡:1s; } divslideshow div[id$=1]{ 背景:FF8888; 转化:translateX0%; z指数:3; } div幻灯片放映div[id$=2]{ 背景:88FF88; 转化:translateX0%; z指数:2; } div幻灯片放映div[id$=3]{ 背景:8888FF; 转化:translateX0%; z指数:1; } divslideshow div[id$=1]。隐藏{ 转化:translateX-100%; } divslideshow div[id$=2]。隐藏{ 转化:translateX-100%; }
我用这个来工作: 谢谢尤塔姆·萨蒙的回答,这让我明白我做错了什么

我基本上让每个函数设置超时并运行下面的函数,然后让最后一个函数运行第一个函数 再一次当时我只需要手动启动第一个,然后它就永远运行下去了

功能滑块1至2{ document.getElementById'slide1'。className=隐藏; setTimeoutslide2to3,4000; } 功能滑块2至3{ document.getElementById'slide2'。className=隐藏; 设置TimeOutslide3到14000; } 功能幻灯片3至1{ document.getElementById'slide1'。className=; document.getElementById'slide2'。className=; setTimeoutslide1to2,4000; } 幻灯片1至2; 幻灯片{ 宽度:100%; 身高:50%; 背景图像:urlwhite-wall.png; } div幻灯片放映div{ 宽度:100%; 身高:继承; 背景重复:无重复; 背景位置:中心; 背景色:rgba0,0,0,0.5; 位置:绝对位置; 过渡:1s; } divslideshow div[id$=1]{ 背景:FF8888; 转化:translateX0%; z指数:3; } div幻灯片放映div[id$=2]{ 背景:88FF88; 转化:translateX0%; z指数:2; } div幻灯片放映div[id$=3]{ 背景:8888FF; 转化:translateX0%; z指数:1; } divslideshow div[id$=1]。隐藏{ 转化:translateX-100%; } divslideshow div[id$=2]。隐藏{ 转化:translateX-100%; }
setTimeout是异步的。它不会阻止执行,直到计时器触发。相反,它只是为将来的某个时间安排一个计时器,并继续执行javascript。因此,您在for循环中计划了300个计时器,全部在三个不同的时间。将一些console.log语句放入slideAtoB函数中,您将看到在同一时刻获得100个logs语句。setTimeout是异步的。它不会阻止执行,直到计时器触发。相反,它只是为将来的某个时间安排一个计时器,并继续执行javascript。因此,您在for循环中计划了300个计时器,全部在三个不同的时间。将一些console.log语句放入slideAtoB函数中,您将看到在同一时间获得100个log语句。您是否意识到这几乎就是我发布的内容?然而,你没有把它标记为被接受的答案?你意识到这几乎就是我发布的吗?然而,你没有把它标记为可接受的答案?