我正在写一个基于iframe的facebook应用程序。现在我想使用相同的html页面来渲染正常的网站以及facebook内的画布页面。我想知道我是否可以确定页面是否已经在iframe内加载或直接在浏览器中加载?


当前回答

“机器人”是对的,但我想补充一点。

在IE7/IE8中,当微软在浏览器中添加标签时,他们破坏了一件事,如果你不小心,就会对你的JS造成严重破坏。

想象一下这样的页面布局:

MainPage.html
  IframedPage1.html   (named "foo")
  IframedPage2.html   (named "bar")
    IframedPage3.html (named "baz")

现在在框架“baz”你点击一个链接(没有目标,加载在“baz”框架),它工作得很好。

如果页面被加载,让我们称之为special.html,使用JS检查“它”是否有一个名为“bar”的父帧,它将返回true(预期)。

现在让我们假设special.html页面在加载时,检查父帧(是否存在和它的名称,如果它是“bar”,它会在bar帧中重新加载自己。如。

if(window.parent && window.parent.name == 'bar'){
  window.parent.location = self.location;
}

到目前为止一切顺利。现在问题来了。

让我们说,不是像平常一样点击原始链接,并在“baz”框架中加载special.html页面,而是单击它或选择在新选项卡中打开它。

当新标签加载时(没有任何父帧!)IE将进入无休止的页面加载循环!因为IE在JavaScript中“复制”了框架结构,这样新的标签确实有一个父标签,并且父标签的名字是“bar”。

好消息是,检查:

if(self == top){
  //this returns true!
}

在新选项卡中确实返回true,因此您可以测试这种奇怪的条件。

其他回答

下面是@magnoz的回答的代码实现。

constructor() {
    let windowLen = window.frames.length;
    let parentLen = parent.frames.length;

    if (windowLen == 0 && parentLen >= 1) {
        this.isInIframe = true
        console.log('Is in Iframe!')
    } else {
        console.log('Is in main window!')
    }
}
if ( window !== window.parent ) 
{
      // The page is in an iframe   
} 
else 
{     
      // The page is not in an iframe   
}

我以前经常检查窗户。父键对我有用,但最近window是一个循环对象,总是有父键,不管有没有iframe。

正如评论所言,很难与窗口相比。父母工作。不确定这是否会工作,如果iframe是完全相同的网页作为父母。

window === window.parent;

在Firefox 6.0扩展(Addon-SDK 1.0)的内容脚本中,接受的答案对我来说不起作用:Firefox在每个:顶级窗口和所有iframe中执行内容脚本。

在内容脚本中,我得到以下结果:

 (window !== window.top) : false 
 (window.self !== window.top) : true

这个输出的奇怪之处在于,无论代码是在iframe中运行还是在顶级窗口中运行,它总是相同的。

另一方面,谷歌Chrome似乎只在顶级窗口内执行我的内容脚本一次,所以上面不会工作。

在两种浏览器的内容脚本中,最终为我工作的是:

 console.log(window.frames.length + ':' + parent.frames.length);

如果没有iframe,则打印0:0,在包含一个框架的顶级窗口中打印1:1,在文档的唯一iframe中打印0:1。

这允许我的扩展在两个浏览器中确定是否存在任何iframes,此外,在Firefox中,如果它是在iframes之一中运行。

这是一段古老的代码,我用过几次:

if (parent.location.href == self.location.href) {
    window.location.href = 'https://www.facebook.com/pagename?v=app_1357902468';
}