2010-11-23 5 views
2

Vor der Frage, lassen Sie mich dies mit der Tatsache voraus, dass ich an einem sehr atypischen Projekt arbeite. Mir geht es nicht um die Sicherheit oder browserübergreifende Auswirkungen. Ich verwende einen benutzerdefinierten Build des Chromium-Projekts.Bestimmen Sie, welcher Rahmen (Name) eine Funktion in JavaScript

Meine Frage ist, wenn ich eine Funktion aus einem anderen Namespace aufrufen, wie kann ich den ursprünglichen Namespace ermitteln?

Zum Beispiel können sagen, ich habe drei Frames:

1. window 
    -> 2. frame1 //is a child of window 
    -> 3. frame2 //is a child of window 

Jetzt können sagen, dass einige JavaScript in window eine Funktion doStuff() hat genannt, dass gebe ich frame1 und frame2 Zugang zu, indem Sie:

var localDoStuff = top.doStuff; 

Innerhalb der Funktion doStuff, gibt es eine Möglichkeit für mich zu bestimmen, welche von frame1 und frame2 es genannt? Wenn ich localDoStuff im Rahmen von frame1 anrufe, kann ich frame1 's DOM window object im Rahmen von doStuff bekommen?

Wenn ich arguments.callee.caller verwende, gibt es mir die String-Darstellung der Funktion, die es aufgerufen. Ich möchte jedoch den -Bereich abrufen, in dem diese Funktion definiert wurde.

I tun haben Zugriff auf die Quelle des Browsers, wenn jemand eine gute, direkte Idee hat, wie der Browser zu ändern, um dies zu ermöglichen.

von Kommentaren Pasted: Ich emuliert im Grunde ein Betriebssystem, das mehrere Anwendungen ausführt. Jede dieser Anwendungen ist ein Iframe, der Zugriff auf eine API hat, die im übergeordneten Frame der Anwendungen definiert ist. Nehmen wir an, diese API hat die Funktion requestFocus() - keine Argumente erlaubt, wie in der API-Spezifikation definiert, die ich implementiere. Um den richtigen iframe-Fokus zu erhalten, müsste ich wissen, welcher Iframe die requestFocus-Funktion genannt wird. Ich weiß, dass dies keine ideale Situation ist - ich habe leider nicht die API-Spezifikation geschrieben ...

Vielen Dank für Ihre Hilfe, ich weiß, dass dies eine wirklich seltsame Frage ist.

+0

Es gibt viele Hacks ich mir vorstellen kann, aber dies scheint nicht sinnvoll zu sein ... Warum wissen würde tun müssen, um Sie, welches Bild es genannt? Wenn Sie das Fensterobjekt benötigen, sollten Sie es mit Ihren Anrufen übergeben. –

Antwort

3

Da verschiedene Rahmen verschiedene Function Konstrukteure haben, können Sie es wie so erkennen:

function doStuff() { 
    if (doStuff.caller instanceof Function) { 
     // called from top 
    } else if (doStuff.caller instanceof frame1.contentWindow.Function) { 
     // called from frame1 
    } ... 
} 

jedoch das funktioniert nicht, wenn die Funktion von Top-Level-Code, in dem Fall doStuff.caller === null genannt wird.

Ich bin wirklich gespannt, ob jemand eine Lösung dafür hat.

+0

@BradSwerdfeger Ich bin nicht dabei, dies als die richtige Antwort zu wählen: 'Function.caller' ist nicht Standard (aber es funktioniert bei großen Browsern) und Pumba80 erwähnt, dass dies nicht, wenn die Funktion von der obersten Ebene aufgerufen wurde. Vor allem, je nachdem, wer dich angerufen hat, ist solch ein schlechtes Design. Es ist jedoch ein cooler Hack. –

1

Eine mögliche Antwort, übergeben Sie das Fenster Objekt entlang in Ihre Argumente und Ihre Funktion wird auf terroristische Handlung welche Fenster in geben wurde. Wenn sie Frames genannt werden, sollten die Fenster einen Namen Eigenschaft.

EDIT: Alternative Lösung

Hier ist eine Technik, die Sie verwenden können, wenn Sie die iframes erstellen und Sie die request Fenster param vom Anrufer innerhalb des iframe zu verbergen:

Sobald Sie das schaffen Wenn Sie iframe verwenden, schließen Sie einen Wrapper requestFocus an das iframe-Fenster an, das ein eigenes Fenster übergibt.

Wenn daher der Inhalt für den iframe zu erzeugen, können Sie eine Funktion wie die folgende in jedem iframe erstellen:

function requestFocus() { 
    parent.requestFocus(window); 
} 

Wie ich schon sagte, ich glaube nicht, dass Sie weg das Fenster bekommen kann von vorbei Objekt, aber Sie können das zumindest vom Anrufer ausblenden. Nur weil Sie die API nicht geschrieben haben, heißt das nicht, dass Sie keine Eingabe haben sollten. nicht nur von JS unterstützt und klingt wie schlechtes Design an erster Stelle, was Sie fordern für (automagically Bestimmung, welcher Rahmen mich genannt)

+0

Hmm, das ist eine großartige Idee. Ich hätte erwähnen sollen, dass ich eine API implementiere, was bedeutet, dass ich nicht von der API-Spezifikation abweichen kann. Leider muss ich mich auf eine ziemlich begrenzte Anzahl von Argumenten beschränken. –

+0

Erklären Sie, warum Sie dieses Verhalten wollen, können Leute Ihnen mit Alternativen helfen –

+0

Ich bin im Grunde emulieren ein Betriebssystem, das mehrere Anwendungen ausführt. Jede dieser Anwendungen ist ein Iframe, der Zugriff auf eine API hat, die im übergeordneten Frame der Anwendungen definiert ist. Nehmen wir an, diese API hat die Funktion requestFocus() - keine Argumente erlaubt, wie in der API-Spezifikation definiert, die ich implementiere. Um den richtigen iframe-Fokus zu erhalten, müsste ich wissen, welcher Iframe die requestFocus-Funktion genannt wird. Ich weiß, dass dies keine ideale Situation ist - ich nicht die API-Spezifikation geschrieben habe, leider ... –

Verwandte Themen