• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

Object erstellen, methode settimeout? HELP

Daggit

New member
Hi,

ich möchte mir ein object in javascript erstellen, welches ich über eine methode(funktion) nach paar sekunden verstecken kann. Hab das mal versucht, jedoch klappt der settimeout aufruf in dem object nicht. weiss jemand warum?

<html>
<head>
<script>
function submenulayer(name,left,top)
{
//Eigenschaten
this.name = name;
this.left = left;
this.top = top;
this.Timer = 0;

//Objekt initialisieren
this.init = function()
{
document.getElementById(this.name).style.left = 100;
}


//Funktion zum verstecken des objektes
this.hide = function()
{
alert(this.name)
//document.getElementById(this.name).style.visibility = "hidden";
}


//Funktion zum verzögerten aufruf
this.hideLayer = function()
{
this.Timer = window.setTimeout(this.hide,500); //HIER IST WAS FALSCH ?
}


//initialisieren
this.init();

}

</script>
</head>

<body>

<div id="MeinLayer" style="position:absolute; visibility:visible; left:0px; background-color:red; width:100px; height:200px;" >
Blablabla
</div>

<script>
//Objekt erstellen
Layer1 = new submenulayer("MeinLayer",2,3);
Layer1.hideLayer();
</script>


</body>
</html>
 
try:

Code:
//Funktion zum verstecken des objektes
this.hide = function()
{
document.getElementById(name).style.visibility = "hidden";
}

dadurch das du "this.hide" in "this.hidelayer" aufrufst,
sucht die funktion "this.hide" dann nach:
"this.this.name"

MFG :cool:
 
hmm also der Fehler liegt nicht in der Verwendung von this.hide oder this.name, denn schliesslich wird ja die richtige Funktion aufgerufen. Lediglich this.name scheint dann nicht mehr korrekt zu sein. Wobei "nicht mehr korrekt" der falsche Ausdruck ist, denn den Namen und das Objekt gibt es dann immer noch, nur this zeigt nicht wie erwartet auf das Objekt, sondern auf "window". Dies liegt darin begründet, dass die Ausführung des Timeout Handler vom Browser nicht im korrekt Objekt-Kontext, sondern im Kontext des window-Objektes ausführt. So wird zwar die richtige Funktion ausgeführt, weil sie als Referenz im setTimeout übergeben wurde, aber die Umgebung ist nicht korrekt.
Obwohl die Lösung von Beatnukem seltsamerweise läuft (zumindest im Opera), zeigt ein alert (this == window) in this.hide eindeutig, dass this in Wirklichkeit kein submenulayer Objekt ist, sondern das Window Objekt darstellt.


Zur Lösung dieses Problems muss man ein wenig in die Trickkiste greifen:
PHP:
this.hideLayer = function()
{
	myThis = this;
	this.Timer = window.setTimeout (function () {myThis.hide ();}, 500); 
}
 
Hi,

erstma danke für die antworten :). Aber nun hab ich ein neues problem. So wie ich das sehe ist die Variable "mythis" in allen objekten gleich, wenn ich sie in objekt A ändere erhält also Objekt B den gleichen inhalt. Das führt dazu das mein Settimeout aufruf nicht mehrere objetkte auf einmal ändern kann.

Ich hab mal ein Script gesehen wo viel mit prototype gemacht wurde. Gibts vielleicht noch andere möglichkeiten damit es funktioniert?

Um den "fehler" zu produzieren einfach beide links schnell anklicken.


Hier mein aktueller Code

<html>
<head>
<script type="text/javascript">
/************************************
* Klasse
* Konstruktor für ein Submenüobjekt
************************************/
function create_submenulayer(name)
{
//Atribute
this.name = name;

//Weitere Aribute
this.hidetimer = 1;


/*****************************
* Methode hide_action()
* versteckt das Object
*****************************/
this.hide_action = function()
{
clearTimeout(this.hidetimer);
document.getElementById(name).style.visibility = "hidden";
}


/********************************
* Methode hide()
* Ruft die Methode "hide_action"
* nach X-sekunden verzögerung auf.
**********************************/
this.hide = function(speed)
{
myThis = this;
clearTimeout(this.hidetimer);
this.hidetimer = window.setTimeout (function () {myThis.hide_action ();}, speed);
}



}
</script>
<script type="text/javascript">
//Objekt erstellen
Layer1 = new create_submenulayer("MeinLayer1");
Layer2 = new create_submenulayer("MeinLayer2");

/*************************
* Methode des übergebenen
* Objekts ausführen
*************************/
function hidetest(objekt)
{
objekt.hide(1000)
}
</script>
</head>
<body>
<div id="MeinLayer1" style="position:absolute; visibility:visible; left:0px; background-color:red; width:100px; height:200px;" >
Layer1
</div>

<div id="MeinLayer2" style="position:absolute; visibility:visible; left:0px; top:250; background-color:red; width:100px; height:200px;" >
Layer2
</div>

<br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br>
<a href="#" onClick="hidetest(Layer1);">[wegmach]</a><br>
<a href="#" onClick="hidetest(Layer2);">[wegmach]</a>
</body>
</html>
 
versuch mal:
Code:
<html>
<head>
<script>
function submenulayer(name,left,top)
{
//Eigenschaten
this.name = name;
this.left = left;
this.top = top;
this.Timer = 0;

//Objekt initialisieren
this.init = function()
{
document.getElementById(this.name).style.left = 100;
}


//Funktion zum verstecken des objektes
this.hide = function()
{
alert(name);
document.getElementById(name).style.visibility = "hidden";
}


//Funktion zum verzögerten aufruf
this.hideLayer = function()
{
alert(this.name);
window.setTimeout(this.hide,500); //HIER IST WAS FALSCH ?
}


//initialisieren
this.init();

}

</script>
</head>

<body>

<div id="MeinLayer" style="position:absolute; visibility:visible; left:100px; background-color:red; width:100px; height:200px;" >
Blablabla
</div>
<div id="MeinLayer2" style="position:absolute; visibility:visible; left:0px; top:250; background-color:green; width:100px; height:200px;">
BluBluBlu
</div>

<script>
//Objekt erstellen
Layer1 = new submenulayer("MeinLayer",2,3);
Layer2 = new submenulayer("MeinLayer2",2,3);
</script>
 <a href="#" onClick="Layer1.hideLayer();">[wegmach]</a><br>
 <a href="#" onClick="Layer2.hideLayer();">[wegmach]</a><br>

</body>
</html>

MFG :cool:

p.s. das iss ja dein orginalscript, hab einfach in der this.hide funktion das this. vor name weggenommen, weil die finktion ja schon aus dem object herrausgestartet wird

also so funzt es jetzt bei mir im IE6 und Firefox 1.0

Achja verpeilt: muss nätürlich heißen: onClick="Layer2.hideLayer();Layer1.hideLayer();"

und dann die alerts mal raus ;)
 
Zuletzt bearbeitet:
Damit es mit mehreren Aufrufen trotzdem klappt müssen zwei Sachen an Deinem Skript geändert werden:
zum einen muß es var myThis = this; heissen und zum anderen solltest Du hidetimer nicht mit 1 initialisieren, denn das ist die ID für den ersten generierten Timer. Eine Schachtelung mit zwei Timern würde dann also durch den Default 1 den ersten Timer löschen.




Beatnukem schrieb:
p.s. das iss ja dein orginalscript, hab einfach in der this.hide funktion das this. vor name weggenommen, weil die finktion ja schon aus dem object herrausgestartet wird
wie gesagt: füge mal ein alert (this == window) ein, und Du wirst sehen, dass die Funktion nicht im richtigen Kontext gestartet wird!
 
ich geb zu, ich bin noch totaler gimp was sowas angeht; bin auch erst seit jetzt 2 monaten wieder son bissel eingestiegen in script-sprachen, aber funktionieren tuts doch meine lösung, oder hab ich da was missverstanden?

MFG Beat Nukem 3D
 
juhu jetzt klappt alles :) nochma DANKE :)

ich habe auch mal so eine definition gesehen:
(sah glaube ich so aus)

this.variable1.variable2 = "hallo"

aber wenn ich mir dann das ganze mir alert ausgebe erhalte ich nur "undefiniert". Weiss einer wie man sowas definiert und wozu das gut ist?
 
Es gibt einen relativ einfachen Workaround für dieses Problem. Dazu musst du dem Objekt den variabelnnamen übergeben:
PHP:
function myObj(wert, varName)
{
    this.show = function()
    {
        alert(this.wert);
    }
    this.timer = function(t)
    {
        window.setTimeout( this.varName + '.show()', t);
    }
    this.varName = varName;
    this.wert = wert;
}
var x1 = new myObj('Ich heiße x1', 'x1');
var x2 = new myObj('Ich heiße x2', 'x2');

x1.timer(1000);
x2.timer(5000);

Das klappt aber nur wenn du den Namen der Variabel kennst.
 
versteh das net ganz :)

warum schreibt man
"this.varName + '.show()'"
und net z.B. this.show() oder this.varname.show()
 
Lass dir doch einfach mal ausgeben was da steht:
PHP:
    this.timer = function(t)
    {
        alert(typeof (this.varName.show) );
        alert(typeof ( this.varName + '.show()') );
    }

window.setTimeout() erwartet als ersten Parameter einen String.
 
ein schlauer schrieb:
Lass dir doch einfach mal ausgeben was da steht:
PHP:
    this.timer = function(t)
    {
        alert(typeof (this.varName.show) );
        alert(typeof ( this.varName + '.show()') );
    }
Dies funktioniert solange, wie die Variable im ausführenden Kontext sichtbar ist.
Ausführender Kontext ist das windows Objekt, somit werden nur globale Variablen sichtbar. Hast Du Objekte in Objekten, die mit einer Timeout Funktion bedacht werden sollen, dann funzt es sicherlich nicht mehr.

ein schlauer schrieb:
window.setTimeout() erwartet als ersten Parameter einen String.
Mit nichten, setTimeout kann ebenso eine Funktion oder eine Funktionsreferenz zugewiesen werden.
 
OK, ich sitze wahrscheinlich zu oft vor meiner alten Kiste (mit 'nem IE 4)

[Edit: ich hab mal grad nachgeschaut http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/settimeout.asp - der IE kann das also seit der 5'er Version]
Das stimmt natürlich alles so. wobei die Einschränkung auf das window Objekt nicht so relevant ist.
Das mit der Funktionsreferenz hab ich nie angwendet weil der IE 4 das nicht kann, aber ich merke grad das sogar NC 4 da mitspielt.

Also - so mit dem var davor und alles klappt Prima:
PHP:
function test(t, n)
{
   this.name = n;
   var x = this;
   this.test = function() { alert('test' + x.name); };
   window.setTimeout(this.test, t);
}
x = new test(2000, 'a');
x = new test(500, 'b');
 
Zuletzt bearbeitet:
ein schlauer schrieb:
Das stimmt natürlich alles so. wobei die Einschränkung auf das window Objekt nicht so relevant ist.
Wenn Du objektorientiert programmieren willst, dann ist das sehr wohl ein nicht zu unterschätzendes Detail, welches für großes Kopfgrübeln sorgen kann.
 
Naja, wer an dieser Stelle (timeout in einem Objekt) nicht schon in's Grübeln gekomen ist, wird sowieso nicht weiter kommen ;-)
 
Zurück
Oben