Rekursion mit Timeout
steckl
- javascript
Hi,
ich habe mir in JS Funktionen geschrieben, mit denen ich per Klick auf Buttons ein Div in eine Richtung wandern lassen kann. Das ganze ist hier zu finden.
Ein Beispiel fuer so eine Funktion waere:
function nachRechts(speed,rek)
{
init();
if(((left+width) < fensterbreite) && (stop == 0))
{
if(!pause)
{
left += speed;
ele.style.left = left + "px";
}
if(rek)
{
window.setTimeout("nachRechts("+speed+",2)",timeout);
}
}
showInfos();
}
Erklaerung:
init() initialisiert die globalen Variablen ele und fensterbreite. Wird jedesmal aufgerufen, da es ja sein kann, dass der Anwender sein Fenster groesser/kleiner macht.
Stop und Pause sind ebenfalls globale variablen, die ausserhalb gesetzt werden koennen um das ganze anzuhalten, bzw. zu unterbrechen.
left ist der Abstand von links, den das Div aktuell hat.
speed ist die Schrittweite, in der das Div verschoben werden soll.
Aufgerufen wird das ganze so:
<button class="bla" onclick="stop=0;pause=0;nachRechts(stepWidth,1);">-</button>
Jetzt zu meinem Problem:
Wenn ich den Button einaml druecke funktioniert alles wunderbar. Wenn ich jedoch oefters draufdruecke oder bevor fertig gescrollt ist einen anderen Button klicke werden die Funktionen parallel ausgefuehrt. (Im IE6 und im FF1.5)
Ich moechte aber, dass erst nochmal gescrollt werden kann, wenn der letzte Scrollvorgang beendet ist.
Hat jemand hierfuer einen Loesungsvorschlag?
Zwei loesungsansaetze, die aber nicht geklappt haben war es zum einen, beim ersten Aufruf (wenn rek == 1) eine globale Variable zu setzen, die erst wieder zurueckgesetzt wird, wenn das Scrollen beendet ist. Aber ich konnte nicht feststellen, ob noch gescrollt wird, weil ja nicht gewartet wird, bis das setTimeout() fertig ist, sondern die Routine einfach durchlaeuft.
Das zweite was mir eingefallen ist war, dass sich die Funktion normal rekursiv aufruft, was aber daran gescheitert ist, dass ich keine "sleep-Funktion" fuer Javascript gefunden habe.
mfG,
steckl
hi,
Zwei loesungsansaetze, die aber nicht geklappt haben war es zum einen, beim ersten Aufruf (wenn rek == 1) eine globale Variable zu setzen, die erst wieder zurueckgesetzt wird, wenn das Scrollen beendet ist. Aber ich konnte nicht feststellen, ob noch gescrollt wird, weil ja nicht gewartet wird, bis das setTimeout() fertig ist, sondern die Routine einfach durchlaeuft.
Ob du das ganze per setTimeout noch mal aufrufst, machst du doch aber von rek abhängig ... also wenn das nicht der Fall ist, Flag zurücksetzen?
Alternative wäre vielleicht, statt setTimeout gleich setInterval zu nutzen. Wenn es dann gerade ein aktives Interval gibt, starte kein neues.
Und das ganze von der Nutzung globaler Variablen zu befreien, also objektorientiert umzusetzen, wäre auch noch schön.
Das zweite was mir eingefallen ist war, dass sich die Funktion normal rekursiv aufruft, was aber daran gescheitert ist, dass ich keine "sleep-Funktion" fuer Javascript gefunden habe.
Die gibt es nicht. Und sie nachzubauen, mit langen While-Schleifen o.ä., ist reichlich unsinnig, weil es den Browser lahmlegt.
gruß,
wahsaga
Hi,
danke fuer die schnelle Antwort.
Ob du das ganze per setTimeout noch mal aufrufst, machst du doch aber von rek abhängig ... also wenn das nicht der Fall ist, Flag zurücksetzen?
Ganz so einfach ist es nicht, aber es waere schon gegangen.Ich stand irgendwie auf dem Schlauch. Aber mit setTimeout finde ich es eh schoener. Danke fuer den Tipp.
Alternative wäre vielleicht, statt setTimeout gleich setInterval zu nutzen. Wenn es dann gerade ein aktives Interval gibt, starte kein neues.
Guter Tipp, so geht es jetzt:
function nachRechts(speed,rek)
{
init();
if((rek==1))
{
if(horInterval)
{
window.clearInterval(horInterval);
}
horInterval = window.setInterval("nachRechts("+speed+",2)",timeout);
}
if(((left+width) < fensterbreite) && (stop == 0))
{
if(!pause)
{
left += speed;
ele.style.left = left + "px";
}
if( (rek == 1) && (!horInterval) )
{
window.setInterval("nachRechts("+speed+",2)",timeout);
}
}
else
{
window.clearInterval(horInterval);
horInterval = 0;
}
showInfos();
}
Und das ganze von der Nutzung globaler Variablen zu befreien, also objektorientiert umzusetzen, wäre auch noch schön.
In diesem kleinen Beispiel ist das wohl nicht so schlimm, da es noch relativ uebersichtlich ist, aber prinzipiell hast du schon recht.
Wie macht man das am besten? Ein globales Objekt, das dann die ganzen globalen Variablen als Attribute hat? Oder das Objekt jedesmal mitschleifen?
Um das ganze komplett OO zu designen (mit Methoden statt Funktionen) fehlen mir wohl noch Kenntnisse ueber OO-Design. Ich will das zwar lernen, aber lieber erstmal in einer anderen Sprache wie C++ oder Java.
mfG,
steckl
Hi,
Um das ganze komplett OO zu designen (mit Methoden statt Funktionen) fehlen mir wohl noch Kenntnisse ueber OO-Design.
Dann hilft Dir möglicherweise dieser Artikel zur Strukturierung von Javascript, denn insbesondere bei diesen Timeout-Geschichten kommt man leicht mit dem Scope durcheinander...
Gruesse, Joachim
Hi,
Dann hilft Dir möglicherweise dieser Artikel zur Strukturierung von Javascript, denn insbesondere bei diesen Timeout-Geschichten kommt man leicht mit dem Scope durcheinander...
Danke, das werd ich mir mal durchlesen.
mfG,
steckl