2010-11-23 5 views
2

Avant la question, laissez-moi vous préface avec le fait que je travaille sur un projet très atypique. Je ne suis pas concerné par la sécurité ou les implications de plusieurs navigateurs. J'utilise une construction personnalisée du projet Chromium.Déterminez quel cadre (nom) a appelé une fonction en JavaScript

Ma question est, si j'appelle une fonction d'un espace de noms différent, comment puis-je déterminer l'espace de noms d'origine?

Par exemple, permet de dire que j'ai trois cadres:

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

Maintenant, permet de dire que certains JavaScript au sein window a une fonction appelée doStuff(), que je donne frame1 et frame2 accès à en allant:

var localDoStuff = top.doStuff; 

Dans la fonction doStuff, est-il un moyen pour moi de déterminer lequel de frame1 et frame2 l'a appelé? i.e: Si j'appelle localDoStuff dans la portée de frame1, puis-je obtenir l'objet fenêtre DOM de frame1 dans la portée de doStuff?

Si j'utilise arguments.callee.caller, il me donne la représentation sous forme de chaîne de la fonction qui l'a appelé. Cependant, je veux obtenir la portée dans laquelle cette fonction a été définie.

I do avoir accès à la source du navigateur si quelqu'un a une bonne, idée orientée de la façon de modifier le navigateur afin de permettre cela.

Collé des commentaires: Je suis émulez essentiellement un système d'exploitation qui exécute plusieurs applications. Chacune de ces applications est un iframe qui a accès à une API définie dans le cadre parent des applications. Disons que cette API a la fonction requestFocus() - aucun argument autorisé, tel que défini dans la spécification de l'API que j'implémente. Afin de donner le bon focus iframe, je devrais savoir quelle iframe a appelé la fonction requestFocus. Je sais que ce n'est pas une situation idéale - je n'ai pas écrit les spécifications API, malheureusement ...

Merci pour votre aide, je sais que c'est une question vraiment étrange.

+0

Il y a beaucoup de hacks je peux penser, mais cela ne semble pas logique ... Pourquoi aurait-vous besoin de savoir quel cadre a appelé? Si vous avez besoin de l'objet fenêtre, vous devez le passer avec vos appels. –

Répondre

3

Depuis différents cadres ont différents Function constructeurs, vous pouvez le détecter comme ceci:

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

Toutefois, cela ne fonctionne pas si la fonction est appelée à partir du code de niveau supérieur auquel cas doStuff.caller === null.

Je suis vraiment curieux de voir si quelqu'un a une solution pour cela.

+0

@BradSwerdfeger Je ne suis pas sur le choix de la bonne réponse: 'Function.caller' n'est pas standard (mais il fonctionne sur les principaux navigateurs) et Pumba80 a mentionné que ce ne sera pas si la fonction a été appelée à partir du niveau supérieur. Surtout, en fonction de qui vous a appelé est un mauvais design. C'est un hack cool cependant. –

1

Une réponse possible, passez l'objet fenêtre le long de vos arguments et votre fonction agira en fonction de la fenêtre qui a été passée. Si elles sont nommées cadres, les fenêtres doivent avoir une propriété name.

EDIT: Solution alternative

Voici une technique que vous pouvez utiliser si vous créez les iframes et que vous voulez cacher la fenêtre requestFocus param de l'appelant dans le iframe:

Une fois que vous créez le iframe, vous branchez un wrapper requestFocus dans la fenêtre d'iframe qui passe sa propre fenêtre.

Par conséquent, lors de la génération du contenu pour l'iframe, vous pouvez créer une fonction comme suit dans chaque iframe:

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

Comme je l'ai dit, je ne pense pas que vous pouvez sortir de passer la fenêtre objet, mais vous pouvez au moins cacher cela de l'appelant. De plus, ce n'est pas parce que vous n'avez pas écrit l'API que vous ne devriez pas avoir d'entrée. Ce que vous demandez (déterminer automagiquement qui cadre m'a appelé) est tout simplement pas pris en charge par JS et sonne comme une mauvaise conception en premier lieu

+0

Hmm, c'est une bonne idée. J'aurais dû mentionner que j'implémente une API, ce qui signifie que je ne peux pas dévier de la spécification de l'API. Malheureusement, je dois m'en tenir à un ensemble assez limité d'arguments. –

+0

Expliquer pourquoi vous voulez ce comportement, les gens peuvent être en mesure de vous aider avec des alternatives –

+0

Je suis essentiellement en train d'émuler un système d'exploitation qui exécute plusieurs applications. Chacune de ces applications est un iframe qui a accès à une API définie dans le cadre parent des applications. Disons que cette API a la fonction requestFocus() - aucun argument autorisé, tel que défini dans la spécification de l'API que j'implémente. Afin de donner le bon focus iframe, je devrais savoir quelle iframe a appelé la fonction requestFocus. Je sais que ce n'est pas une situation idéale - je n'ai pas écrit la spécification de l'API, malheureusement ... –

Questions connexes