window.setTimeout() wartet nicht...
thecreep
- javascript
Hi,
ich schreibe grade einen Fader (wo bei das Fader-Framework eine gute Vorlage darstellt). Allerdings funktioniert mein window.setTimeout nicht wirklich, bzw. es wartet nicht.
Hier mal der Quellcode:
function Fader(id)
{
this.div = document.getElementById(id);
this.id = id;
this.ai = 0;
this.fadeTime = 100;
this.timeOut = 3000;
this.repeat = false;
this.images = new Array("./IMAGES/Fahrer/borch.jpg","./IMAGES/Fahrer/micha.jpg");
this.createImages = function(){
this.div.innerHTML="";
for(i=0;i<this.images.length;i++)
this.div.innerHTML+="<img style='opacity: "+(i==0?"1":"0")+";' src='"+this.images[i]+"'>";
}
this.addImage = function(img){
this.images[this.images.length]=img;
}
//Es geht mir um den Folgenden Code-Fetzen:
this.Fade = function(step) {
step = step || 0;
step+=2;
var imgs=this.div.getElementsByTagName("IMG");
imgs[this.ai+1].style.opacity=step/100;
if(step<100)
window.setTimeout(this.Fade(step), this.fadeTime);
}
}
In meiner HTML-Seite erstelle ich im onload ein neues Fader-Objekt:
var myfader = new Fader("fadediv");
Dann habe ich noch einen Button:
<input type=button value="create&fade" onclick="myfader.createImages();myfader.Fade();">
Momentan ist die fadeTime auf 3000 Millisekunden eingestellt, quasi ja 3 Sekunden wird in der Fade-Routine das aktuelle Img-Objekt immer um 2% sichtbarer.
Heißt quasi, dass der Transparenz-Übergang ca. 2,5 Minuten dauern müsste. Nun rast es aber durch und ist innerhalb eines Bruchteils einer Sekunde fertig.
Fehlermeldungen bekomme ich keine, also wo liegt mein Fehler?
Im Fader-Framework wirds genauso gemacht aber da funktioniert es ja.
Falls es wichtig ist, ich benutze Firefox 3.0.15
MfG
thecreep
Hallo,
bist du dir sicher, dass setTimeout nicht mit eine String versehen werden muss als erstem Parameter? Isoliertes Testen vielleicht?
Gruß
jobo
window.setTimeout(this.Fade(step), this.fadeTime);
Und hier ist auch schon der Fehler, denn das "this.Fade(step)" in dieser Anweisung führt die Funktion sofort aus. Um sie verzögert aufzurufen, müsste es entweder also String übergeben oder in eine Funktion gekapselt werden - mit der ersten Lösung besteht jedoch das Problem, dass "this" in diesem Kontext nicht verfügbar ist, so dass eine vorher definierte Funktion die bessere Wahl darstellt:
var timeoutFn = function() { this.Fade(step); }
window.setTimeout(timeoutFn, this.fadeTime);
Gruß, LX
Hallo,
var timeoutFn = function() { this.Fade(step); }
window.setTimeout(timeoutFn, this.fadeTime);
nicht window.setTimeout("timeoutFn()",timeVar) ?
Also als String?
Gruß
jobo
nicht window.setTimeout("timeoutFn()",timeVar) ?
Also als String?
Nein, besser bzw. hier nur schöner, ist die Funktionsreferenz.
Struppi.
Hallo,
Nein, besser bzw. hier nur schöner, ist die Funktionsreferenz.
Funktionsreferenz ist Funktionsname ohne "()" ?
Gruß
jobo
Nein, besser bzw. hier nur schöner, ist die Funktionsreferenz.
Funktionsreferenz ist Funktionsname ohne "()" ?
Kann man so sagen, ja.
Das ist aber auch eine:
var f = function(txt) { alert(txt);};
f('Hallo');
Struppi.
Hallo,
Nein, besser bzw. hier nur schöner, ist die Funktionsreferenz.
Funktionsreferenz ist Funktionsname ohne "()" ?Kann man so sagen, ja.
Das ist aber auch eine:
var f = function(txt) { alert(txt);};
f('Hallo');
Unter Funktionsreferenz versteht man scheinbar zwei Sachen. Beim Googlen kommt haufenweise eine Auflistung von Funktionen (zB. PHP), also ein Manual.
Oder:
"window.onerror = Funktionsreferenz – Führt die angegebene Funktion beim Auftreten eines Fehlers aus. Es muss eine Referenz auf die Funktion angegeben werden, also window.onerror = funktion und nicht window.onerror = funktion()."
"funktion" ist dann die Funktionsreferenz, "funktion()" der aufruf der funktion. Ums aber genau zu wissen: Was ist bei deinem Beispiel die Funktionsreferenz? Der aufruf f("Hallo")? Das müsst ja bei SetTimeout als String verpackt sein, sonst "funzt es nicht, oder?"
setTimeout("f('hallo')",timeVar);
Gruß
jobo
"funktion" ist dann die Funktionsreferenz, "funktion()" der aufruf der funktion. Ums aber genau zu wissen: Was ist bei deinem Beispiel die Funktionsreferenz? Der aufruf f("Hallo")? Das müsst ja bei SetTimeout als String verpackt sein, sonst "funzt es nicht, oder?"
f ist die Referenz auf die Funktion.
Nein der Aufruf muss nicht als String verpackt werden.
setTimeout("f('hallo')",timeVar);
In dem Fall benutzt man besser ein closure:
window.setTimeout( fucntion() { f('hallo')}, timeVar);
Struppi.
"Referenz" ist schlicht und einfach ein Bezeichner, ein Variablenname, der in diesem Fall eben auf eine Funktion hinweist.
Man kann Funktionen auch ohne Referenz definieren und ausführen (bspw. um Code zu kapseln):
(function() {
...
})()
Was window.setTimeout betrifft: wenn es einen String bekommt, wird dieser innerhalb des Timeouts evaluiert - also das Equivalent von eval ausgeführt (und eval ist so böse, wie es sich auf Englisch anhört!).
Darum ist es gegebenenfalls besser, innerhalb von window.setTimeout eine Funktion zu übergeben.
Gruß, LX
Hallo,
(function() {
...
})()
(...)() wird sofort ausgeführt?
Gruß
jobo
Wenn zwischen den Klammern eine Funktion steht bzw. zurückgegeben wird, ja.
Gruß, LX
Hallo,
Wenn zwischen den Klammern eine Funktion steht bzw. zurückgegeben wird, ja.
äh, und was, wenn nicht? ()()? bringt das was?
Gruß
jobo
Wenn zwischen den Klammern eine Funktion steht bzw. zurückgegeben wird, ja.
äh, und was, wenn nicht? ()()? bringt das was?
Ja, du hast einen lokalen Kontext.
Struppi.
äh, und was, wenn nicht? ()()? bringt das was?
Ja, einen Fehler, da "undefined" nicht als Funktion ausgeführt werden kann.
Gruß, LX
Hallo,
In dem Fall benutzt man besser ein closure:
window.setTimeout( fucntion() { f('hallo')}, timeVar);
"closure", weil es die Funktion "einschließt", oder besser "kapselt"?
Gruß
jobo
"closure", weil es die Funktion "einschließt", oder besser "kapselt"?
http://aktuell.de.selfhtml.org/artikel/javascript/organisation/#closures
Struppi.
Im Fader-Framework wirds genauso gemacht aber da funktioniert es ja.
Nein, mit Sicherheit nicht.
Leider bist du hier nicht mehr auf meinen Einwurf eingegangen, da dieses Problem hier mit dem dort vermutlich zusammenhängt.
Du musst dir im klaren sein, in welchen Kontext ein Code aufgerufen wird. In deinem Fall ist this nicht das this mit dem du rechnest. Da window.setTimeout() im Kontext von window aufgerufen wird, folglich ist this == window
Dummerweise machst du aber noch einen zweiten Fehler. Du benutzt einen falschen 1. Parameter in setTimeout. Dieser muss entweder eine Zeichenkette sein, die dann als JS Code interpretiert wird oder eine Funktionsreferenz, so wie im Faderframework.
Der einfachste Weg die Problematik des Kontext zu beseitigen ist eine lokale Kopie des Objekt und für die Funktionsreferenz, ein closure. Beides nutzt das Faderframework. Lies dir noch mal diese Seite durch.
Struppi.