2016-08-04 13 views
1

Ich versuche, diesen Code auszuführen, um eine Diashow von 3 Bildern zu machen, aber es funktioniert nicht richtig. Die Diashow wird einmal ausgeführt, stoppt dann aber ...setTimeout funktioniert nicht mit for-Schleife

Unten finden Sie meine JavaScript-, CSS- und HTML-Dateien. Wenn Sie das Code-Snippet ausführen, wird die Diashow einmal ausgeführt.

Der HTML deklariert im Grunde ein Container-Div mit den Folien als Divs mit einem bestimmten Hintergrundbild. (Für diese Frage habe ich die Bilder in Farben geändert, so dass Sie die Diashow in Aktion sehen können)

Die CSS deklariert die Position der einzelnen Bilder der Diashow, wenn sie gerade und ausgeblendet ist.

Das JavaScript durchläuft die Folien und gibt jedem eine Klasse von "versteckt", wenn sie sich aus dem Blickfeld bewegen sollen. Am Ende bringt es die erste Folie zurück, indem alle "versteckten" Klassen entfernt werden.

Ich bin ziemlich sicher, dass das Problem in der JavaScript mit der Funktion setTimeout ist, da jedes Mal, wenn ich die Funktionen in der Konsole ausführen funktioniert perfekt, aber wenn ich versuche, sie automatisch in JS ausgeführt wird es nur einmal ausgeführt.

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

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

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

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

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

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

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

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

+0

'SetTimeout()' ist asynchron. Es blockiert die Ausführung erst, wenn der Timer ausgelöst wird. Stattdessen plant es nur einen Timer für eine zukünftige Zeit und setzt die Ausführung Ihres Javascript fort. Also planst du 300 Timer in deiner 'for'-Schleife, alles zu drei verschiedenen Zeiten. – jfriend00

+0

Setzen Sie einige console.log-Anweisungen in Ihre slideAtoB-Funktionen und Sie werden sehen, dass Sie 100 Log-Anweisungen alle gleichzeitig erhalten. – morgancodes

Antwort

1

Ich habe es mit dieser Arbeit: (Danke Yotam Salmon für Ihre Antwort, das ist, was mir geholfen unter stehe, was ich falsch gemacht habe)

Ich habe im Grunde jede Funktion, um die Zeitüberschreitung einzustellen und den folgenden zu starten, dann habe ich den letzten, um den ersten wieder zu starten. alles, was ich brauchte, war dann, das erste manuell zu starten, dann lief es einfach für immer.

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{ 
 
\t width:100%; 
 
\t height:50%; 
 
\t background-image:url("white-wall.png"); 
 
} 
 

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

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

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

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

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

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

+0

Ist dir klar, dass dies fast genau das ist, was ich gepostet habe? Aber Sie haben es nicht als die akzeptierte Antwort markiert? – Josh

+1

Du hast recht @Josh, sorry, ich habe deine Antwort nicht gesehen –

4

Wenn Sie setTimeout(), wird der Code nicht warten, bis das Timeout beenden zu. Das bedeutet, dass Ihre for-Schleife 100 Mal nach 2 Sekunden, weitere 100 Mal nach 4 Sekunden und weitere 100 Mal nach 6 Sekunden ausgeführt wird.

Stattdessen können Sie die Timeouts nach Abschluss des dritten Frames erneut festlegen.

Ein Beispiel für eine einfache Schleife mit Timeouts:

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

Diese^ist gut. Ein schlechtes Beispiel wäre:

Die erste wird 100 Mal mit einem Intervall von 1 Sekunde ausgeführt, letztere wird 1 Mal ausgeführt.

0

Wie andere erwähnt haben, macht Ihre Schleife effektiv nichts, da setTimeout asynchron ist.

Eine Möglichkeit, um das gewünschte Ergebnis zu erzielen, besteht darin, die Rückruffunktion in jedem zu setzen. Stellen Sie dann eine andere Funktion ein, die die Timeouts löscht. Um für immer zu loopen, entfernen Sie einfach die stopTransitions Funktion und ihren Aufrufer.

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(); 
1

könnten Sie gleichen Effekt ohne JS Verwendung mit CSS3-Animationen

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

(nicht genau den gleichen Code, sollten Sie mit der Zeit und die Stile ein wenig spielen)
.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; 
} 
Verwandte Themen