Probleme mit Funktionsaufruf
wiberg
- javascript
Hallo,
die Funktion (eig. eine Methode) "move" ruft sich selbst nach einer gewissen Zeit auf - leider scheint sie nicht mehr zu wissen, dass sie eine Methode von einem Objekt ist. Sie kann dann nicht mehr auf die Eigenschaften des Objekts zugreifen. Warum?
Code:
das Objekt sieht so aus:
function Sn(color) {
this.posx = Math.floor(size / 2);
this.color = color;
this.move = move;
}
function move() {
document.getElementById(this.posx).style.color = "#" + this.color;
window.setTimeout("this.move();",this.speed);
}
Hi wiberg,
die Funktion (eig. eine Methode) "move" ruft sich selbst nach einer gewissen Zeit auf - leider scheint sie nicht mehr zu wissen, dass sie eine Methode von einem Objekt ist. Sie kann dann nicht mehr auf die Eigenschaften des Objekts zugreifen. Warum?
Weil beim zweiten mal, die Function aus einer Function heraus aufgerufen wird und nicht aus einem Objekt. Aus dem Grund führt das this dann zu nichts mehr.
MfG, Dennis.
Hi!
function move() {
document.getElementById(this.posx).style.color = "#" + this.color;
window.setTimeout("this.move();",this.speed);}
^^
Der Fehler liegt hier:------------->
Dort gehört nämlich kein Semikolon hin. Richtig müsste es so heißen:
windowsetTimeout("this.move()", this.speed);
---------------------------------------------------------
Grüße,
Fabian St.
gruss wiberg,
function move() {
document.getElementById(this.posx).style.color = "#" + this.color;
window.setTimeout("this.move();",this.speed);
-----------------------^^^^^^^^^^^^^^
spaetestens an dieser stelle ist der interpreter ueberfordert, da "this.move();"
von der funktion "setTimeout" nicht mehr im richtigen kontext evaluiert werden
kann oder einfacher ausgedrueckt: "setTimeout" kann "this.move()" nirgendwohin
zuordnen, da "this" als zeichenkette innerhalb von "setTimeout" nicht mehr den
bezug zur methode "move" aufrechterhalten kann;
}
es muss also ein weg gefunden werden, der die referenz auf das objekt trotz der
gerade beschriebenen einschraenkungen durch "setTimeout" permanent ermoeglicht;
zur veranschaulichung schlage ich ersteinmal die "unsaubere" loesung vor, mit
namen von globalen variablen zu arbeiten; jedes objekt, welches spaeter die
"move"-methode aufrufen soll, benoetigt eine zusaetzliche eigenschaft, in der
sein globaler variablenname hinterlegt wird;
dieser name wird dann beim erstmaligen aufruf der methode mitgegeben und von
ebenjener dann permanent durchgeschliffen;
dein abgewandeltes bsp.:
function Sn(color) {
//this.posx = Math.floor(size/2);
this.color = color;
this.move = move;
}
function move(globalName,objectSpeed) {
//document.getElementById(this.posx).style.color = "#" + this.color;
alert("color = " + window[globalName].color + "\nspeed = " + objectSpeed);
window.setTimeout(("window["" + globalName + ""].move("" + globalName + ""," + objectSpeed + ")"),objectSpeed);
}
var x = new Sn("ffcc00");
x.globalName = "x";
x.speed = 3000;
x.move(x.globalName,x.speed);
ausserdem ist es ratsam, eigenschaften und methoden, die allen instanzen eines
konstruktors gemein sind, als prototypen der konstruktor-funktion zu realisieren -
fuer den oben beschriebenen fall saehe das so aus:
var Sn = function(color) {
//this.posx = Math.floor(size/2);
this.color = color;
};
Sn.prototype.move = function(globalName,objectSpeed) {
//document.getElementById(this.posx).style.color = "#" + this.color;
alert("color = " + window[globalName].color + "\nspeed = " + objectSpeed);
window.setTimeout(("window["" + globalName + ""].move("" + globalName + ""," + objectSpeed + ")"),objectSpeed);
};
Sn.prototype.speed = 3000; // time in msec;
var x = new Sn("ffcc00");
x.globalName = "x";
x.move(x.globalName,x.speed);
falls jetzt noch interesse an einem dieses thema ausfuehrlich diskutierenden
und beschreibenden thread besteht, empfehle ich als einstieg folgendes posting -
http://forum.de.selfhtml.org/archiv/2004/3/77173/#m445704 - sowie die
dort verlinkte javascript-loesung:
http://www.pseliger.de/jsExtendedApi/jsApi.Object.selfReferences.dev.js
viel erfolg - peterS. - pseliger@gmx.net
Vielen Dank für diese ausführliche Hilfe, aber das ist nicht ganz das, was ich suche. Ich habe mal eine Methode ausgegraben, die sich selbst ohne Probleme als Methode einer existierenden Instanz aufrufen konnte:
function Effect() {
this.moveL = moveL;
}
function moveL(element_id,start,end,i) {
if(typeof(i) == 'undefined')
var i = 50;
var new_pos = end + ((start - end) / (51 - i));
//alert(end + " + ((" + start + " - " + end + ") / (51 - " + i + ")) = " + new_pos);
document.getElementById(element_id).style.left = new_pos + "px";
if(i > 0) {
--i;
window.setTimeout("this.moveL('" + element_id + "'," + start + "," + end + "," + i + ");",10);
}// else alert("Endwert: " + new_pos);
}
ich gebe zu, dass ist ein bisschen holprig programmiert, aber es erfüllte seinen Zweck. Man konnte damit ein Objekt ziemlich fesch durch die Gegend flitzen lassen... und wie man sieht, ruft sich moveL() selbst mit einem Timeout auf (übrigens MIT Semikolon). Seltsam, ich finde, dass meine jetzige Funktion dieser sehr ähnlich sieht, dennoch funktioniert sie nicht.