absolute adresse eines objects
Darkwind
- javascript
Hallo,
Dies ist mein erster Beitrag hier und dann auch nicht mal eine Frage. ^^
Mein Problem war, dass ich an eine Flash-Datei einen Namen einer Funktion übergeben wollte. Diese Funktion sollte dann aus Flash über getURL, in der Seite, wo das Flash-Object eingebettet ist aufgerufen werden.
// Flash Actionsscript
var js = "try{"+jsfunc+"(\"foo\")"}catch(window){}";
getURL("javascript:"+js, "_self");
flashvars="jsfunc=window.a.b.c.d.func";
war mir zu statisch, da hardcoded. Schließlich sollte die Function func auch in anderen Objekten sein können.
Ich wollte die Sache dynamisch haben.
Dies ist im Allgemeinen bei Javascript aber ein Problem, da ein Objekt nicht die Objekte kennt, die auf es referenzieren.
Wie kann man also dann herausfinden, wie die absolute Adresse eines Objektes ist?
Mein Ansatz war also der folgende. Jede Webseite kennt das window Object. "Globale Variablen" hängen alle an diesem Object. Von window kommt man auch an das Eltern- und somit an Geschwisterobjekte. Kurz, man hat ein sehr breites Spektrum, welches man über Referenzierung absuchen kann.
Jedoch gibt es auch ein Problem, denn es handelt sich nicht um einen Baum, sondern ein allgemeines Netz. Das bedeutet, dass man beim "Entlanghangeln" an den Referenzierungen wieder zu einem bereits durchlaufenen Objekt kommen kann. Dies ist zu verhindern um Endlosschleifen zu vermeiden.
Der nachfolgende Code ist ein Proof of Concept und nicht vollkommen ausgefeilt.
// JavaScript Document
Object.prototype.getAbsoluteAddress = function() {
var search = this;
var obj = window;
var path = {objects:[window],names:["window"]};
var scanChildObject = function(obj) {
for (var key in obj) {
if (search == obj[key]) {
path.objects.push(obj[key]);
path.names.push(key);
return true;
}
if (typeof obj[key] == 'object') {
var enter = true;
for (var i=0;i<path.objects.length && enter;i++)
enter = path.objects[i]!=obj[key];
if (enter) {
path.objects.push(obj[key]);
path.names.push(key);
if (scanChildObject(obj[key]))
return true;
path.objects.pop();
path.names.pop();
}
}
}
return false;
}
if (!scanChildObject(obj))
return "not found";
else
return path.names.join('.');
}
window.z = {beta:{gamma:{delta:"delta"}}}; // Objekt mit Unterobjekten
window.z.beta.a = window.z; // Einen Loop einbauen
alert(window.z.getAbsoluteAddress());
alert(window.z.beta.gamma.delta.getAbsoluteAddress());
Die Funktion getAbsoluteAddress ist nun ein Kind vom allgemeinen Object, hängt also an jedem Objekt der Seite. Wer dies nicht mag, kann auch mit einer statischen Funktion arbeiten.
window.getAbsoluteAddress = function(search) {
var obj = window;
...
Ich hoffe jemandem damit geholfen zu haben.
Für Kommentare bin ich offen.
Danke fürs Lesen.
Gruß,
Darkwind
Mein Problem war, dass ich an eine Flash-Datei einen Namen einer Funktion übergeben wollte. Diese Funktion sollte dann aus Flash über getURL, in der Seite, wo das Flash-Object eingebettet ist aufgerufen werden.
// Flash Actionsscript
var js = "try{"+jsfunc+"("foo")"}catch(window){}";
getURL("javascript:"+js, "_self");
>
> flashvars="jsfunc=window.a.b.c.d.func";
Wozu ist das gut? Wenn du in jsfunc die Referenz auf die Funktion hast, kannst du diese einfach aufrufen jsfunc(); oder als closure übergeben, je nachdem was da passieren soll.
> Der nachfolgende Code ist ein Proof of Concept und nicht vollkommen ausgefeilt.
Auch hier ist mir nicht klar wo du hinwillst, warum reicht dir das this nicht?
Struppi.
Hallo Stupi,
»» Mein Problem war, dass ich an eine Flash-Datei einen Namen einer Funktion übergeben wollte. Diese Funktion sollte dann aus Flash über getURL, in der Seite, wo das Flash-Object eingebettet ist aufgerufen werden.
»»
»» ~~~Javascript
»» // Flash Actionsscript
»» var js = "try{"+jsfunc+"("foo")"}catch(window){}";
»» getURL("javascript:"+js, "_self");
»»
> »»
> »» flashvars="jsfunc=window.a.b.c.d.func";
>
> Wozu ist das gut? Wenn du in jsfunc die Referenz auf die Funktion hast, kannst du diese einfach aufrufen jsfunc(); oder als closure übergeben, je nachdem was da passieren soll.
Die Sache ist die, dass ich in der dynamischen Umgebung nicht weiß, wie ich ein Objekt und dessen Funktion an Flash übergeben soll. Das ist das Problem. Das Flashobjekt bekommt seine Parameter über flashvars. Und dies ist nun einmal eine Zeichenkette, also nicht für den Transport eines Objektes geeignet, sondern nur für eine Referenz auf dieses.
>
> »» Der nachfolgende Code ist ein Proof of Concept und nicht vollkommen ausgefeilt.
>
> Auch hier ist mir nicht klar wo du hinwillst, warum reicht dir das this nicht?
>
Der Code erzeugt in Javascript den absoluten Pfad zur Instanz eines Objektes als Zeichenkette. Genau das was ich für die Parameterübergabe an das Flashobjekt benötige.
> Struppi.
Der Code erzeugt in Javascript den absoluten Pfad zur Instanz eines Objektes als Zeichenkette. Genau das was ich für die Parameterübergabe an das Flashobjekt benötige.
Ach so, ActionScript. Damit kenne ich mich nicht aus.
Und über den Umweg einer Eventfunktion geht es auch nicht?
function flashEvent() {
if(flashEvent.callback) flashEvent.callback();
}
flashEvent.callback = function() {
jsfunc("foo");
};
getURL("javascript:flashEvent()", "_self");
Struppi.
»» Der Code erzeugt in Javascript den absoluten Pfad zur Instanz eines Objektes als Zeichenkette. Genau das was ich für die Parameterübergabe an das Flashobjekt benötige.
Ach so, ActionScript. Damit kenne ich mich nicht aus.
Und über den Umweg einer Eventfunktion geht es auch nicht?
function flashEvent() {
if(flashEvent.callback) flashEvent.callback();
}flashEvent.callback = function() {
jsfunc("foo");
};getURL("javascript:flashEvent()", "_self");
>
Leider ist das auch wieder zu statisch, da ich mit jsfunc bereits auf Variablen im Objekt zugreifen möchte. Bei deinem Lösungsweg stünde ich wieder vor meinem Anfangsproblem, dass ich wieder statisch die Methode vorgeben müsste.
Mein Flashobjekt hat die Aufgabe Werte aus dem Netz zu laden und an die Funktion eines beliebigen Objektes in Javascript zu übergeben.
Mit deinem Ansatz könnte ich zwar die Werte an die Seite übergeben, hätte auf der Seite aber wieder eine statische Function (flashEvent). Das wollte ich vermeiden und habe deshalb meinen Objectsuchansatz entwickelt.
> Struppi.
Gruß,
Darkwind
» »» Der Code erzeugt in Javascript den absoluten Pfad zur Instanz eines Objektes als Zeichenkette. Genau das was ich für die Parameterübergabe an das Flashobjekt benötige.
»
» Ach so, ActionScript. Damit kenne ich mich nicht aus.
»
» Und über den Umweg einer Eventfunktion geht es auch nicht?
»
» ~~~javascript
function flashEvent() {
» if(flashEvent.callback) flashEvent.callback();
» }
»
» flashEvent.callback = function() {
» jsfunc("foo");
» };
»
» getURL("javascript:flashEvent()", "_self");
»
> »
>
> Leider ist das auch wieder zu statisch, da ich mit jsfunc bereits auf Variablen im Objekt zugreifen möchte. Bei deinem Lösungsweg stünde ich wieder vor meinem Anfangsproblem, dass ich wieder statisch die Methode vorgeben müsste.
Das verstehe ich nicht, wo siehst du das Problem? Du kannst die callback Funktion doch so schreiben wie du sie brauchst.
> Mein Flashobjekt hat die Aufgabe Werte aus dem Netz zu laden und an die Funktion eines beliebigen Objektes in Javascript zu übergeben.
Ja, wunderbar, dass sollte so gehen. Du kannst der Eventfunktion auch Parameter übergeben.
> Mit deinem Ansatz könnte ich zwar die Werte an die Seite übergeben, hätte auf der Seite aber wieder eine statische Function (flashEvent). Das wollte ich vermeiden und habe deshalb meinen Objectsuchansatz entwickelt.
Der keine statische Funktion ist?
Du hast jetzt einen Ansatz der sich mühsam durch alle Objektinstanzen durchwühlen muss (was im IE zu Problemen führen kann), mein Vorschlag braucht nichts weiter als eine definierte Eventfunktion und eine flexible callbackfunktion.
Das ist übrigens ein Vorgehen das in JS bei vielen Abläufen eingesetzt wird.
Struppi.