Objekte und Events
Michael Kaufmann
- javascript
Hallo,
ich habe ein Problem mit dem Aufrufen von Objektmethoden über einen Eventhandler. Hier der vereinfachte Code:
<html>
<head><title>Test</title></head>
<script language="JavaScript">
function feld_mm()
{
alert(this.feld_div);
}
function feld(feld_div)
{
this.feld_div = feld_div;
this.feld_mm = feld_mm;
this.feld_div.document.onmousedown = this.feld_mm; // hier kommt undefined als Ausgabe ! Warum ?
this.feld_div.document.captureEvents(Event.MOUSEDOWN);
}
function init()
{
feld1=new feld(window.document.elm1);
feld2=new feld(window.document.elm2);
feld2.feld_mm(); // Hier kommt als Ausgabe ObjectLayer, also das richtige
}
</script>
<body onload="init()" bgcolor="#ffffff">
<div id="elm1" style="position:absolute; top:10px; left:50px;"><img src="images/feld1.gif" border=0"></div>
<div id="elm2" style="position:absolute; top:40px; left:50px;"><img src="images/feld2.gif" border=0"></div>
</body>
</html>
Eigentlich sollte, wenn an auf das Feld klickt ein Fensterchen aufpopen, in dem steht: [ObjectLayer].
Anstatt dessen steht dort aber undefined. Es sieht so aus, als würde nicht die Methode feld1.feld_mm() aufgerufen werden, sondern die Funktion feld_mm().
Das Problem liegt wohl an der Zeile:
this.feld_div.document.onmousedown = this.feld_mm;
im Konstruktor des Objekts (function feld();)
Dummerweise habe ich keine Ahnung warum! Geht das vielleicht gar nicht ?
Ich benutze NN4.73 für Linux (dummerweise gibt es gerade bei den Events unterschiede zwischen den Linux und Windows Versionen)
danke und tschüss Michael
Hallo Michael
function feld_mm()
{
alert(this.feld_div);
}
»»
function feld(feld_div)
{
this.feld_div = feld_div;
this.feld_mm = feld_mm;
»»
this.feld_div.document.onmousedown = this.feld_mm; // hier kommt undefined als Ausgabe ! Warum ?
this.feld_div.document.captureEvents(Event.MOUSEDOWN);
}
function init()
{
»»
feld1=new feld(window.document.elm1);
feld2=new feld(window.document.elm2);
»»
feld2.feld_mm(); // Hier kommt als Ausgabe ObjectLayer, also das richtige
}
Ich bin kein Profi, und ich weiss auch nicht, obs was bringt, aber du hast die Funktion feld_mm() im Konstruktor nicht als Methode des Objekts definiert. Du definierst da nur, dass das Objakt die Variablen feld_div und feld_mm besitzt, aber nicht, dass du mit der Methode feld_mm() auf feld_div zugreifen kannst.
Meiner Meinung nach sollte der Konstruktor irgendwie so aussehen:
// function feld(feld_div, feld_mm){
// this.feld_div = feld_div;
// this.feld_mm = feld_mm;
// this.feld_mm() = feld_mm(); // !!!
// this.feld_div.document.onmousedown = this.feld_mm;
// this.feld_div.document.captureEvents(Event.MOUSEDOWN);
// }
Abgesehen davon, was ist "mm" überhaupt ??
Ich weiss nicht, obs stimmt, oder ob ich nur Blödsinn labere, aber ich würd es sowieso anders probieren. Ich weiss nicht wie es anders geht, aber das was du mir hier vorgelegt hast, wäre mir eindeutig zu kompliziert ;-)
Grüsse
Bernhard
Hallo Bernhard
Ich bin kein Profi, und ich weiss auch nicht, obs was bringt, aber du hast die Funktion feld_mm() im Konstruktor nicht als Methode des Objekts definiert. Du definierst da nur, dass das Objakt die Variablen feld_div und feld_mm besitzt, aber nicht, dass du mit der Methode feld_mm() auf feld_div zugreifen kannst.
Ich bin leider auch kein Profi :-) Ich will aber mal einer werden !
Meiner Meinung nach sollte der Konstruktor irgendwie so aussehen:
// function feld(feld_div, feld_mm){
Meiner Meinung nach, muss ich die Funktion feld_mm nicht
extra übergeben, da sie global ist und damit sowieso im
Konstruktor bekannt ist.
// this.feld_div = feld_div;
// this.feld_mm = feld_mm;
// this.feld_mm() = feld_mm(); // !!!
das kann auf keinen Fall so sein, denn mit den () nach
dem Funktionsnamen wäre die Funktion this.feld_mm()
der Rückgabewert der Funktion feld_mm. Ausserdem wäre
das ein(e) falsche(r) Syntax.
// this.feld_div.document.onmousedown = this.feld_mm;
// this.feld_div.document.captureEvents(Event.MOUSEDOWN);
// }
Abgesehen davon, was ist "mm" überhaupt ??
mm sollte eigentlich mousemove heissen...irgendwie ist
es dann aber doch mousedown geworden :-)
Ich weiss nicht, obs stimmt, oder ob ich nur Blödsinn labere, aber ich würd es sowieso anders probieren. Ich weiss nicht wie es anders geht, aber das was du mir hier vorgelegt hast, wäre mir eindeutig zu kompliziert ;-)
hmm, Blödsinn ?? naja, es funzt so nicht.
Das ist so "kompliziert", da das wirkliche Script (ich
wollte keine 300+ Zeilen Code hier reinstellen) ein
Scroll Object darstellen soll, mit dem man "einfach"
(auch mehrere) scrollbare Layer in eine Seite einbinden
können soll. Für sowas bietet sich ein Objekt halt sehr
gut an.
tschüss Michael
Hallo Michael!
das kann auf keinen Fall so sein, denn mit den () nach
dem Funktionsnamen wäre die Funktion this.feld_mm()
der Rückgabewert der Funktion feld_mm. Ausserdem wäre
das ein(e) falsche(r) Syntax.
Stimmt, die Klammern gehören weg, aber Funktionen sind in Javascript genauso Objekte. Daher kann man auch funktionen auf funktionen "zuweisen" ! -gibt's echt, ehrlich! Nur gehören die Klammern weg, da jedoch deine Funktion dann genauso heissen würde wie deine Variable müsstest du dir einen anderen Namen für eine(n) der beiden einfallen lassen.
Vgl:
var fenster = new Window();
var feld = new Array();
var funktion = new Function();
... im Grunde das selbe Schema !
Ich hab dir einen Auszug aus einem Skriptum von einer meiner Übungen auf der Uni zum Thema Javascript:
Ja, wir lernen sowas wirklich auf der Uni ;-)
Aber frag nicht wie ... ! - SELFHTML-Forum is the place to be!!
<html>
<head>
<script language="JavaScript">
function zeige_umfang (r) { // Deklaration einer Objektmethode (=Funktion)
var umfang, pi=3.14;
alert("Kreis "+this.name + " mit Umfang " + (pi*2*r));
// this.name greift auf Komponente name der
// aktuellen Instanz von Objekt kreis zu.
}
function position (x,y) { // Deklaration von Objekt position
this.posx = x; // mit 2 Komponenten posx und posy
this.posy = y; // this zeigt auf aktuelle Objektinstanz.
}
function kreis (name,radius,pos) { // Deklaration von Objekt kreis
this.name = name;
this.radius = radius;
this.pos = pos; // Objekt als Objektkomponente
this.zeige_umfang = zeige_umfang; // Methodenzuweisung !!!!!!!
}
</script>
</head>
<body>
<script language="JavaScript">
pos1 = new position(0.0,0.0);
kreis1 = new kreis("Kreis1",1.23,pos1);
kreis1.zeige_umfang (kreis1.radius);
</script>
</body>
</html>
Du musst es mir ja nicht glauben, aber über JavaScript hab ich mich schon längst aufgehört zu wundern ;-)
Dieses Beispiel kannst du Strg-Kopieren und austesten. Es funktioniert einwandfrei :-)
Grüsse
Bernhard
Hallo Bernhard,
's hat leider immer noch nicht funktioniert!
Stimmt, die Klammern gehören weg, aber Funktionen sind in Javascript genauso Objekte. Daher kann man auch funktionen auf funktionen "zuweisen" ! -gibt's echt, ehrlich! Nur gehören die Klammern weg, da jedoch deine Funktion dann genauso heissen würde wie deine Variable müsstest du dir einen anderen Namen für eine(n) der beiden einfallen lassen.
Meiner Meinung nach hast du recht !
Ich habe dein Script mal ein bisschen umgeschrieben, so dass es
Eventhandler (Mausklick ins Browserfenster) benutzt um die Methode
kreis1.zeige_umfang() aufzurufen. Dann tritt das selbe Problem ein wie
bei mir :-(
<html>
<head>
<script language="JavaScript">
function zeige_umfang ()
// hier habe ich etwas geändert, da ich nicht weiss, wie ich bei
// Eventhandlern irgendwelche Werte übergibt. Da diese Funktion
// aber sowieso auf this.radius zugreifen kann muss man den Radius
// ja nicht extra übergeben.
{ // Deklaration einer Objektmethode (=Funktion)
var umfang, pi=3.14;
alert("Kreis "+this.name + " mit Umfang " + (pi*2*this.radius));
// this.name greift auf Komponente name der
// aktuellen Instanz von Objekt kreis zu.
}
function position (x,y)
{ // Deklaration von Objekt position
this.posx = x; // mit 2 Komponenten posx und posy
this.posy = y; // this zeigt auf aktuelle Objektinstanz.
}
function kreis (name,radius,pos)
{ // Deklaration von Objekt kreis
this.name = name;
this.radius = radius;
this.pos = pos; // Objekt als Objektkomponente
this.zeige_umfang = zeige_umfang; // Methodenzuweisung !!!!!!!
document.onmousedown = this.zeige_umfang; // Entweder hier, was besser wäre (man stelle sich 1000
document.captureEvents(Event.MOUSEDOWN); // Objekte vor, hier nur 2 Zeilen, unten wären es 2000)
}
</script>
</head>
<body>
<script language="JavaScript">
pos1 = new position(0.0,0.0);
kreis1 = new kreis("Kreis1",1.23,pos1);
kreis1.zeige_umfang(); // hier kommt wieder da selbe Ergebnis wie vorher.
// document.onmousedown = kreis1.zeige_umfang; // oder hier, egal beides
// document.captureEvents(Event.MOUSEDOWN); // funktioniert nicht
</script>
</body>
</html>
Du musst es mir ja nicht glauben, aber über JavaScript hab ich mich schon längst aufgehört zu wundern ;-)
Naja, ich glaube dir schon, ich habe nur meine Glauben an NN
verloren. Manchmal kommt es vor dass er wegen JavaScripts abstürtzt
oder dass NN4.7 keine Scripts ausführen kann, die NN4.73 ohne Probleme
ausführt (teilweise ist es sogar andersrum, z.B. mit dem - im Variablennamen)
Dieses Beispiel kannst du Strg-Kopieren und austesten. Es funktioniert einwandfrei :-)
Das stimmt, ich glaube aber auch nicht, dass darin mein Problem liegt.
Es liegt vielmehr daran, dass der Eventhandler die falsche funktion
aufruft. Ich habe auch schon Funktionen umbenannt, so dass die
Objektmethode anders heisst als die Funktion. Aber all das hat nicht
geholfen. Ich könnte es natürlich auch mit eval machen. Das wäre dann
aber nicht mehr OOP, sondern ein Mix aus normal und OOP.
tschüss Michael