如何使用 jQuery 公开 IFrame 的 DOM?

Posted

技术标签:

【中文标题】如何使用 jQuery 公开 IFrame 的 DOM?【英文标题】:How to expose IFrame's DOM using jQuery? 【发布时间】:2010-12-11 20:38:15 【问题描述】:

我有一个代表特定 IFrame 的原型。该原型有一个名为 GoToUrl(...) 的函数,可以在 IFrame 中打开给定的 url。

我的问题是:如何创建一个“InternalDOM”属性并使该属性引用内部 IFrame 的“窗口”对象(根 DOM 对象)?这样:如果我的 IFrame 公开了一个页面,其中有一个对象 X 在它的“窗口”对象中,我可以这样做:

MyFrameObject.GoToUrl(pageXurl);
MyFrameObject.InternalDOM.X

任何帮助将不胜感激。

PS:我会接受不一定与 jQuery 相关的答案,但我更喜欢 jQuery 解决方案。

【问题讨论】:

【参考方案1】:

要获取框架的window 对象,您可以使用window.frames 数组:

var iframewindow= frames['iframe_name'];

这要求你给<iframe> 一个老式的name 属性而不是id。或者,如果您知道页面上 iframe 的顺序,您可以对它们进行数字索引:

var iframewindow= frames[0];

从 DOM 中的 iframe 元素获取 iframe 窗口通常更灵活,但这需要一些兼容性代码来应对 IE:

var iframe= document.getElementById('iframe_id');
var iframewindow= iframe.contentWindow? iframe.contentWindow : iframe.contentDocument.defaultView;

jQuery 定义了contents() 方法来获取document 节点,但它并没有为您提供从documentwindow 的跨浏览器方式,所以您仍然坚持使用:

var iframe= $('#iframe_id')[0];
var iframewindow= iframe.contentWindow? iframe.contentWindow : iframe.contentDocument.defaultView;

这并不是一个真正的大胜利。

(注意:使用 jQuery 进行跨框架脚本编写时要非常小心。每个框架都需要自己的 jQuery 副本,并且来自一个框架副本的方法不一定适用于另一个框架的节点。跨框架脚本是一种充满陷阱的话题。)

【讨论】:

esqsoft.com/javascript_examples/iframe_talks_to_parent - 关于跨 iframe 脚本的一个很好的例子和解释 我更喜欢$('#iframe-id').get(0).contentWindow【参考方案2】:

总结一下

从父页面访问 iframe 内容

var iframe = $('iframe').contents(); // iframe.find('..') ...

从 iframe 访问父页面内容

var parent = $(window.parent.document); // parent.find('..') ...

这仅适用于父页面和 iframe 页面位于同一域中的情况。

编辑:加载子 iframe 示例:

html

<iframe id="iframe1" src="iframe1.html"></iframe>
<iframe id="iframe2" src="iframe2.html"></iframe>

父级js

$(function () 
    var iframe1 = null,
        iframe2 = null;

    // IE8/7
    var frameInterval = window.setInterval(function () 
        iframe1 = $('#iframe1').contents();
        iframe2 = $('#iframe2').contents();
        if ($('head', iframe1).length && $('head', iframe2).length) 
            window.clearInterval(frameInterval);
        
    , 100);

    // on iframe loaded
    $('#iframe1').on('load', function (e) 
        iframe1 = $('#iframe1').contents();
    );
    $('#iframe2').on('load', function (e) 
        iframe2 = $('#iframe2').contents();
    );
);

包括 IE9 在内的所有主流浏览器都使用 on('load') 行。只有 IE8/7 需要间隔块。

【讨论】:

谢谢,节省了我一些时间:)【参考方案3】:

更新@RoyiNamir 的评论:

var frames = window.frames || window.document.frames;

用于 iframe 中的窗口。

frames["myIframeId"].window

用于 iframe 中的文档

frames["myIframeId"].window.document

iframe 中的正文

frames["myIframeId"].window.document.body

使用 jquery 的 iframe 中的正文

var iframeBody = $(frames["myIframeId"].window.document).contents().find("body");

重要提示: 您应该始终检查文档的状态是否为“完成”以便使用它

if (frames["myIframeId"].window.document.readyState=="complete")

   //ok

else

   //perform a recursive call until it is complete

【讨论】:

@andres descalzo 自从您撰写此答案以来,我一直没有调查更改,但 window.document.frames 不再起作用,至少在 Firefox 和 Chrome 中不起作用。编辑您的帖子。 @RoyiNamir 感谢您的澄清,在 IE 中工作正常,但与其他浏览器不兼容

以上是关于如何使用 jQuery 公开 IFrame 的 DOM?的主要内容,如果未能解决你的问题,请参考以下文章

使用 JQuery 将事件处理程序添加到 iframe

如何使用 jquery 从 iframe 获取内容? [复制]

如何使用 jquery 从 IFrame 本身更改 IFrame 样式?

如何使用 jQuery 进入 iframe [重复]

如何在 Wordpress 插件中使用 jQuery 从 Iframe 调用 Iframe?

jquery如何在html页面取得iframe的元素