在提出问题之前,让我先说明我正在开展一个非常非典型的项目。我不关心安全性或跨浏览器的含义。我正在使用Chromium项目的自定义版本。
我的问题是,如果我从不同的命名空间调用函数,我该如何确定原始命名空间?
例如,假设我有三个框架:
1. window
-> 2. frame1 //is a child of window
-> 3. frame2 //is a child of window
现在,我们可以说window
中的某些JavaScript有一个名为doStuff()
的函数,我可以通过以下方式frame1
和frame2
访问:
var localDoStuff = top.doStuff;
在doStuff
函数中,有没有办法让我确定frame1
和frame2
中的哪一个调用了它?即:如果我在localDoStuff
范围内致电frame1
,我可以在frame1
的范围内获取doStuff
的DOM窗口对象吗?
如果我使用arguments.callee.caller
,它会给我调用它的函数的字符串表示。但是,我想获得定义该函数的范围。
我做可以访问浏览器的来源,如果有人对如何修改浏览器有一个好的,有针对性的想法,以便允许这样做。
粘贴评论: 我基本上是在模拟运行多个应用程序的操作系统。这些应用程序中的每一个都是一个iframe,可以访问应用程序父框架中定义的API。假设这个API有函数requestFocus() - 不允许参数,正如我正在实现的API规范中所定义的那样。为了给出正确的iframe焦点,我必须知道哪个iframe称为requestFocus函数。我知道这不是一个理想的情况 - 不幸的是我没有编写API规范......
感谢您的帮助,我知道这是一个非常奇怪的问题。
答案 0 :(得分:3)
由于不同的帧具有不同的Function
构造函数,因此您可以像这样检测它:
function doStuff() {
if (doStuff.caller instanceof Function) {
// called from top
} else if (doStuff.caller instanceof frame1.contentWindow.Function) {
// called from frame1
} ...
}
但是,如果从顶级代码调用该函数,则此方法不起作用doStuff.caller === null
。
我真的很想知道是否有人有解决方案。
答案 1 :(得分:1)
一个可能的答案,在你的参数中传递窗口对象,你的函数将根据传入的窗口进行操作。如果它们是命名框架,则窗口应该有一个名称属性。
编辑:替代解决方案
如果您要创建iframe,并且想要隐藏iframe中调用者的requestFocus窗口参数,可以使用以下技术:
创建iframe后,将包装器requestFocus插入iframe的窗口,该窗口通过自己的窗口。
因此,在为iframe生成内容时,您可以在每个iframe中创建如下所示的函数:
function requestFocus() {
parent.requestFocus(window);
}
就像我说的那样,我认为你不能逃避传递窗口对象,但你至少可以将其隐藏在调用者之外。另外,仅仅因为你没有编写API,并不意味着你不应该有任何输入。你要求的是什么(自动确定哪个框架叫我),JS不支持它,听起来像是糟糕的设计