【问题标题】:How to access parent Iframe from JavaScript如何从 JavaScript 访问父 iframe
【发布时间】:2010-10-30 10:12:36
【问题描述】:

嗯,我有一个 IFrame,它调用同一个域页面。 我的问题是我想从这个被调用的页面(来自 JavaScript)访问来自这个父 iframe 的一些信息。如何访问此 iframe?

详细信息:有几个像这个一样的 iframe,可以加载相同的页面,因为我正在编写 Windows 环境。我打算关闭这个 iframe,这就是为什么我需要知道我应该从他内部关闭哪个。我有一个数组来保存对这些 iframe 的引用。

编辑:动态生成 iframe

【问题讨论】:

  • 即使 iframe 是动态生成的,你也可以通过使用某种计数器来分配一个新的唯一 ID,最后你不需要知道 ID,但是你可以轻松搜索,看我的答案。

标签: javascript iframe


【解决方案1】:

您还可以将名称和 ID 设置为相等的值

<iframe id="frame1" name="frame1" src="any.html"></iframe>

这样您就可以在子页面中使用下一个代码

parent.document.getElementById(window.name);

【讨论】:

  • 可能对每个人来说都不是很明显,但是通过这种方法可以访问父级的库对象(只有在父级已经加载了库的情况下)。示例:使用 parent.$('#something') 访问 jQuery
  • 本方案兼容IE5+兼容怪癖模式。
  • 即使在 2016 年,作为解决 IE 打印 iframe 内容太小的问题的一部分,这也很有效。但为什么它会起作用? window.name 返回一个字符串。使用 window.name 与仅将 id 名称作为不起作用的字符串传递有什么不同。)?
  • 嗨,它不能在 Chrome 59 上运行.. :VM111:1 Uncaught DOMException: Blocked a frame with origin "xxx" 无法访问跨域框架。
  • 如果没有设置 CORS,Chrome 会查看与跨域相同文件夹中的文件。他们说这是为了安全。设置 CORS 需要一个服务器。如果检测到 Chrome,则向用户发送设置服务器或更改浏览器的消息。
【解决方案2】:

只需从您的框架页面调用window.frameElement。 如果页面不在框架中,则frameElement 将是null

另一种方式(在框架内获取窗口元素不那么简单),但为了完整起见:

/**
 * @param f, iframe or frame element
 * @return Window object inside the given frame
 * @effect will append f to document.body if f not yet part of the DOM
 * @see Window.frameElement
 * @usage myFrame.document = getFramedWindow(myFrame).document;
 */
function getFramedWindow(f)
{
    if(f.parentNode == null)
        f = document.body.appendChild(f);
    var w = (f.contentWindow || f.contentDocument);
    if(w && w.nodeType && w.nodeType==9)
        w = (w.defaultView || w.parentWindow);
    return w;
}

【讨论】:

  • 谢谢!适用于 IE 6+、FF 和 Chrome!
  • window.frameElement 在 window 和 iframe 具有不同的域时返回 null,即跨域消息传递。
  • @Qwerty 你找到解决办法了吗?
  • @AjayPatidar 我想我放弃了。 :(
  • @Qwerty 一种可能的解决方案是使用 iframe 作为“代理”在不同域的页面之间发送消息。例如,sysend.js 使用 postMessage() 执行此操作。
【解决方案3】:

我建议使用postMessage API

在您的 iframe 中,调用:

window.parent.postMessage({message: 'Hello world'}, 'http://localhost/');

在包含 iframe 的页面中,您可以监听如下事件:

window.addEventListener('message', function(event) {
      if(event.origin === 'http://localhost/')
      {
        alert('Received message: ' + event.data.message);
      }
      else
      {
        alert('Origin not allowed!');
      }

    }, false);

顺便说一句,也可以调用其他窗口,而不仅仅是 iframe。

在 John Resigs 博客 here 上阅读有关 postMessage API 的更多信息

【讨论】:

  • 我认为这显然是最好的答案,&lt;iframe&gt; 内容不必知道任何关于父级的信息,反之亦然。他们只需要遵守简单的消息契约。太棒了!
  • @HomrZodyssey 父域仅作为安全机制可用,如果不知道可以设置'*'
  • 在客户端上使用'*'。由于未设置服务器,所有其他解决方案都会在 Chrome 浏览器上将客户端文件夹中的文件视为非同源文件而出错。这是最好且唯一的解决方案:dyn-web.com/tutorials/iframes/postmessage
  • DOMException: 阻止原点为“null”的框架访问跨域框架。
【解决方案4】:

老问题,但我也遇到了同样的问题,并找到了获取 iframe 的方法。这只是遍历父窗口的 frames[] 数组并针对运行代码的窗口测试每个帧的 contentWindow 的问题。示例:

var arrFrames = parent.document.getElementsByTagName("IFRAME");
for (var i = 0; i < arrFrames.length; i++) {
  if (arrFrames[i].contentWindow === window) alert("yay!");
}

或者,使用 jQuery:

parent.$("iframe").each(function(iel, el) {
  if(el.contentWindow === window) alert("got it");
});

此方法无需为每个 iframe 分配一个 ID,这在您的情况下很好,因为它们是动态创建的。我找不到更直接的方法,因为您无法使用 window.parent 获取 iframe 元素 - 它直接进入父窗口元素(跳过 iframe)。所以循环遍历它们似乎是唯一的方法,除非你想使用 ID。

【讨论】:

  • 更新:这并不像宣传的那样工作,我不得不使用 contentWindow.document===document。不知道为什么。同样在某些浏览器中,我使用了 contentDocument。嗯,我喜欢!
  • 抱歉,我承认我只在 Firefox 中测试过。 :) 但是我在多个浏览器中使用 jQuery 方法和 contentWindow 取得了成功。
  • 更新:我发现你也可以使用window.frameElement,但我不确定哪些浏览器支持它。
  • 我认为这种类型的东西不再起作用了;你得到一个跨域错误。
  • @AndrewMao 问题是关于同源文件,所以没有理由得到跨源问题。
【解决方案5】:

您可以使用parent 访问父页面。所以要访问一个函数,它将是:

var obj = parent.getElementById('foo');

【讨论】:

  • 凯文,问题是要知道 id。我有几个 iframe,我想从里面的代码访问它们
  • 访问跨域框架时仍会得到“阻止具有源“other-localhost:8000”的框架。”
  • DOMException: 阻止原点为“null”的框架访问跨域框架。
【解决方案6】:

一旦 iframe 的 id 被设置,您就可以从内部文档访问 iframe,如下所示。

var iframe = parent.document.getElementById(frameElement.id);

在 IE、Chrome 和 FF 中运行良好。

【讨论】:

  • 这似乎是一种复杂的var iframe = frameElement
  • frameElement 在当前窗口上下文中返回对象,但是 parent.document.getElementById(frameElement.id) 在父窗口上下文中返回对象,你不能用 frameElement 运行父窗口的 javascript 函数,在 jsfiddle 中尝试如果可以的话,给我和例子。
【解决方案7】:

也许只是使用

window.parent

进入您的 iframe 以获取调用框架/窗口。如果你有多个调用框架,你可以使用

window.top

【讨论】:

    【解决方案8】:

    试试这个,在您的父框架中设置您的 IFRAME,如下所示:

    <iframe id="frame1" src="inner.html#frame1"></iframe>
    <iframe id="frame2" src="inner.html#frame2"></iframe>
    <iframe id="frame3" src="inner.html#frame3"></iframe>
    

    注意每一帧的id在src中作为anchor传递。

    然后在您的内部 html 中,您可以通过 location.hash 访问它加载的框架的 ID:

    <button onclick="alert('I am frame: ' + location.hash.substr(1))">Who Am I?</button>
    

    然后您可以访问 parent.document.getElementById() 以从 iframe 内部访问 iframe 标签

    【讨论】:

    • 是的,这将是最合乎逻辑的解决方案,但有时我需要更改 iframe 的 src.. 并且每个请求都传递这个哈希或 GET 参数并不好..
    • 为什么每次都传递哈希是不好的?它只对浏览器可见,对服务器不可见,并且不会像 get 参数那样影响缓存。
    【解决方案9】:
    // just in case some one is searching for a solution
    function get_parent_frame_dom_element(win)
    {
        win = (win || window);
        var parentJQuery = window.parent.jQuery;
        var ifrms = parentJQuery("iframe.upload_iframe");
        for (var i = 0; i < ifrms.length; i++)
        {
            if (ifrms[i].contentDocument === win.document)
                return ifrms[i];
        }
        return null;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-26
      • 1970-01-01
      相关资源
      最近更新 更多