setTimeout函数不能用于for循环

时间:2016-08-04 22:31:35

标签: javascript html for-loop slideshow settimeout

我试图运行此代码来制作3张图片的幻灯片,但它无法正常工作。幻灯片播放一次,但之后就停止了......

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

HTML基本上是将幻灯片声明为带有特定背景图像的div的容器div。 (对于这个问题,我将图像更改为颜色,以便您可以看到正在播放的幻灯片)

当幻灯片显示在普通视图中并隐藏时,CSS会声明每个幻灯片图像的位置。

JavaScript循环播放幻灯片,为每个幻灯片提供一个"隐藏"什么时候他们应该离开视线。最后,它通过删除所有隐藏的"来恢复第一张幻灯片。类。

我非常确定这个问题出在带有setTimeout函数的JavaScript中,因为无论何时我在控制台中运行它都能完美运行,但是当我尝试自动将它们设置为在我的JS中运行它只运行一次



function slide1to2(){
	document.getElementById('slide1').className = "hidden";
	clearTimeout(s1to2);
}
function slide2to3(){
	document.getElementById('slide2').className = "hidden";
	clearTimeout(s2to3);
}
function slide3to1(){
	document.getElementById('slide1').className = "";
	document.getElementById('slide2').className = "";
	clearTimeout(s3to1);
}

for(i=0; i<100; i++){
	s1to2 = window.setTimeout(slide1to2, 2000);
	s2to3 = window.setTimeout(slide2to3, 4000);
	s3to1 = window.setTimeout(slide3to1, 6000);
}
&#13;
div#slideshow{
	width:100%;
	height:50%;
	background-image:url("white-wall.png");
}

div#slideshow div{
	width:100%;
	height:inherit;
	background-repeat:no-repeat;
	background-position:center;
	background-color:rgba(0,0,0,0.5);
	position:absolute;
	transition:1s;
}

div#slideshow div[id$="1"]{
	background:#FF8888;
	transform:translateX(0%);
	z-index:3;
}

div#slideshow div[id$="2"]{
	background:#88FF88;
	transform:translateX(0%);
	z-index:2;
}

div#slideshow div[id$="3"]{
	background:#8888FF;
	transform:translateX(0%);
	z-index:1;
}

div#slideshow div[id$="1"].hidden{
	transform:translateX(-100%);
}

div#slideshow div[id$="2"].hidden{
	transform:translateX(-100%);
}
&#13;
<div id="slideshow">
	<div id="slide1"></div>
	<div id="slide2"></div>
	<div id="slide3"></div>
</div>
&#13;
&#13;
&#13;

4 个答案:

答案 0 :(得分:4)

当您setTimeout()时,代码不会等待超时完成。这意味着你的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次。

答案 1 :(得分:1)

你可以在不使用JS和CSS3动画的情况下获得相同的效果(不完全相同的代码,你应该玩时间和样式一点点)

https://plnkr.co/edit/2AtRK7z9OJhs4AwX82rx?p=preview

.animation--slideshowAnimation {
  width: 100%;
  height: 500px;
  background-size: cover;
  background-position: 50%;
  background-repeat: no-repeat;

  animation-duration: 12s;
  animation-name: slideshowAnimation;
  animation-delay: 0;
  animation-iteration-count: infinite;
  animation-direction: forward;
}

答案 2 :(得分:1)

我得到了它: (感谢Yotam Salmon的回答,那是什么帮助我理解我做错了什么)

我基本上得到了每个函数来设置超时并运行下一个,然后我得到了最后一个再次运行第一个。我需要的只是手动启动第一个,然后才能永远运行。

function slide1to2(){
    document.getElementById('slide1').className = "hidden";
    setTimeout(slide2to3, 4000);
}
function slide2to3(){
    document.getElementById('slide2').className = "hidden";
    setTimeout(slide3to1, 4000);
}
function slide3to1(){
    document.getElementById('slide1').className = "";
    document.getElementById('slide2').className = "";
    setTimeout(slide1to2, 4000);
}

slide1to2();
div#slideshow{
	width:100%;
	height:50%;
	background-image:url("white-wall.png");
}

div#slideshow div{
	width:100%;
	height:inherit;
	background-repeat:no-repeat;
	background-position:center;
	background-color:rgba(0,0,0,0.5);
	position:absolute;
	transition:1s;
}

div#slideshow div[id$="1"]{
	background:#FF8888;
	transform:translateX(0%);
	z-index:3;
}

div#slideshow div[id$="2"]{
	background:#88FF88;
	transform:translateX(0%);
	z-index:2;
}

div#slideshow div[id$="3"]{
	background:#8888FF;
	transform:translateX(0%);
	z-index:1;
}

div#slideshow div[id$="1"].hidden{
	transform:translateX(-100%);
}

div#slideshow div[id$="2"].hidden{
	transform:translateX(-100%);
}
<div id="slideshow">
    <div id="slide1"></div>
    <div id="slide2"></div>
    <div id="slide3"></div>
</div>

答案 3 :(得分:0)

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

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

https://jsfiddle.net/24aLyg5v/

var timeout1, timeout2;

function slide1to2(){
    document.getElementById('slide1').className = "hidden";
    document.getElementById('slide2').className = "";
    timeout1 = window.setTimeout(slide2to1, 2500);
}

function slide2to1(){
    document.getElementById('slide2').className = "hidden";
    document.getElementById('slide1').className = "";
    timeout2 = window.setTimeout(slide1to2, 2500);
}

function stopTransitions() {
    clearTimeout(timeout1);
    clearTimeout(timeout2);
}

window.setTimeout(stopTransitions, 20000);
slide1to2();