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

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

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

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

任何帮助将不胜感激。

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

【问题讨论】:

    标签: javascript jquery dom


    【解决方案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 副本,并且来自一个框架副本的方法不一定适用于另一个框架的节点。跨框架脚本是一种充满陷阱的话题。)

    【讨论】:

    【解决方案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 中工作正常,但与其他浏览器不兼容
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-10
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    • 2012-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多