Experten! timeout und Objekt
Struppi
- javascript
Hallo alle JS Experten ;-)
Eigentlich ist das keine Frage, sondern ich brauch ein bisschen Input ob und wie ich das neu gelernte am besten umsetze.
Zum Problem:
Fast jeder kennt das Problem man bastelt sich ein schönes Objekt und dann möchte man mit diesem einen timer benutzen. Das geht aber nicht, da die funktion setTimeout einen string als ersten Parameter erwartet und ein Objekt als String darzustellen ist nicht möglich.
Nun hab ich (ich glaube es war der JS Newsgroup) einen schönen Trick/workaround gelesen, der auch sogar im IE 4 funktionert.
Das sieht so aus:
<script type="text/javascript">
function myObj(name)
{
this.name = name;
this.wert = 0;
}
myObj.prototype.timer = function()
{
if( this.wert && !confirm('Der Zähler ist bei: ' + this.wert + '\n\nWeiter?') ) return;
this.wert++;
window.setTimeout(this.name + '.timer()', 500);
}
var o = new myObj('o');
o.timer();
</script>
http://home.arcor.de/struebig/computer/javascript/test/test timeout.html
Geht das eleganter?
(ich weiss dass man in neuren Browsern auch ein anonyme Funktion definieren kann, das läuft aber nicht in meinem IE 4)
Es ist ja manchmal nicht so einfach den Variabelnname als String zu übergeben (bei einem Array z.b.), kann man den zur Laufzeit irgendwie rausfinden?
Gibt es vielleicht in den Tiefen von .prototype .constructor usw. noch andere Möglichkeiten?
Und wo geht das nicht?
Struppi.
Hallo Struppi,
Geht eigentlich ganz einfach:
<script type="text/javascript">
function myObj(name)
{
this.name = name;
this.wert = 0;
}
window.setTimeout(myObj(),1000);
</script>
Wie nachzulesen, erwartet settimeout auch einen Zeiger auf ne Funktion.
Also einfach den Funktionsnamen als Argument übergeben.
window.setTimeout ( vCode, iMilliSeconds [, sLanguage] )
Parameters
vCode Required. Variant that specifies the function pointer or string that indicates the code to be executed when the specified interval has elapsed.
Gruss
Oliver
Geht eigentlich ganz einfach:
Nö, eben nicht.
<script type="text/javascript">
function myObj(name)
{
this.name = name;
this.wert = 0;
}window.setTimeout(myObj(),1000);
Das wäre ja nicht myObj
Sondern du musst erst eins anlegen:
var o = new myObj();
und jetzt?
wie gesagt ich möchte innerhalb des Objetes zur Laufzeit einen Timer setzten. Das ist zum Beispiel nötig, wenn du einen Layer langsam über den Bildschirm bewegen möchtest und diesen als Objekt definierst.
Dazu musst du die Bewegen Funktion immer wieder aufrufen, das würde bei dir so aussehen:
function myObj(name)
{
this.name = name;
this.wert = 0;
}
myObj.prototype.move = function()
{
if(this.wert < ende) window.setTimeout(this.move(),1000);
}
var o = new myObj();
var ende = 100;
o.move();
klapt aber nicht.
</script>
Wie nachzulesen, erwartet settimeout auch einen Zeiger auf ne Funktion.
Also einfach den Funktionsnamen als Argument übergeben.
Wo hast du das gelesen?
http://www.mozilla.org/docs/dom/domref/dom_window_ref115.html#1021427
schreibt:
ID = window.setTimeout("funcName", delay)
Parameters
funcName is the name of the function for which you want to set a delay.
vCode Required. Variant that specifies the function pointer or string that indicates the code to be executed when the specified interval has elapsed.
OK hier:
http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/settimeout.asp
Das heißt es funktionert zumindest in allen IE Browsern mit einer anonymen Funktion. Aber nicht so wie du es schreibst.
sondern so:
function myObj(name)
{
this.name = name;
this.wert = 0;
}
myObj.prototype.move = function()
{
window.status = 'wert:' + this.wert;
var s = this;
if(++this.wert < ende)
window.setTimeout(function(){s.move()},1000);
}
var o = new myObj();
var ende = 100;
o.move();
Ich werd das mal in allen Browsern ausprobieren, ist zumindest flexibler als die mit dem String.
Struppi.
gruss Struppi,
Fast jeder kennt das Problem man bastelt sich ein schönes Objekt und dann
möchte man mit diesem einen timer benutzen. Das geht aber nicht, da die
funktion setTimeout einen string als ersten Parameter erwartet und ...
... ein Objekt als String darzustellen ist nicht möglich.
richtig - aber man kann die objekt-referenz mit einem string umschreiben:
http://www.pseliger.de/jsExtendedApi/jsApi.Object.selfReferences.dev.js
die forums-suche spuckt zwei relevante links aus, in denen der weg
zur loesung dieses problems hoffentlich nachvollzogen werden kann:
http://suche.de.selfhtml.org/cgi-bin/such.pl?suchausdruck=selfreference&lang=on&feld=alle&index_5=on&index_6=on&hits=100
function myObj(name)
{
this.name = name;
this.wert = 0;
}
myObj.prototype.timer = function()
{
if( this.wert && !confirm('Der Zähler ist bei: ' + this.wert + '\n\nWeiter?') ) return;
this.wert++;
window.setTimeout(this.name + '.timer()', 500);
}
...
Geht das eleganter?
naja, ob das eleganter waere, weis ich nicht, denn es saehe dann so aus:
function MyObject() {
this.setSelfReference();
this.value = "something";
//...
}
MyObject.prototype.timer = function () {
if (this.value && !confirm("Der Zähler ist bei: " + this.value + "\n\nWeiter?")) {
return;
}
++this.value;
setTimeout(this.getSelfReference() + ".timer()",500);
};
um das gefrickel in "setTimeout" kommt man in diesem fall nicht
drumherum, man spart sich aber die namensgebung!
ausserdem verwalten sich die referenzen immer dann von selbst,
wenn eine referenz gesetzt oder geloescht wird. das ist ziemlich
praktisch, wenn man zur laufzeit mit einer grossen und darueber
hinaus noch schwankenden anzahl von objekten arbeiten muss, die
diese art von selbstreferenzierung in anspruch nehmen.
(ich weiss dass man in neuren Browsern auch ein anonyme Funktion
definieren kann, das läuft aber nicht in meinem IE 4)
ob "jsApi.Object.selfReferences.js" im 4er msie laeuft, muss noch
getestet werden (kein verpflichtender aufruf).
viel spass beim basteln - peterS. - pseliger@gmx.net