嵌套 iframe,又名 iframe Inception

Posted

技术标签:

【中文标题】嵌套 iframe,又名 iframe Inception【英文标题】:Nested iframes, AKA Iframe Inception 【发布时间】:2013-02-26 22:42:58 【问题描述】:

我正在使用 jQuery 访问 div id="element"。

<body>
    <iframe id="uploads">
        <iframe>
            <div id="element">...</div>
        </iframe>
    </iframe>
</body>

所有 iframe 都在同一个域中,没有 www / non-www 问题。

我已成功选择第一个 iframe 中的元素,但没有选择第二个嵌套 iframe。

我已经尝试了一些东西,这是最近的一次(也是一次非常绝望的尝试)。

var iframe = jQuery('#upload').contents();
var iframeInner = jQuery(iframe).find('iframe').contents();
var iframeContent = jQuery(iframeInner).contents().find('#element');

// iframeContent is null

编辑: 为了排除时间问题,我使用了点击事件并等待了一段时间。

jQuery().click(function()
   var iframe = jQuery('#upload').contents().find('iframe');
   console.log(iframe.find('#element')); // [] null
);

有什么想法吗? 谢谢。

更新: 我可以像这样选择第二个 iframe...

var iframe = jQuery('#upload').contents().find('iframe');

现在的问题似乎是 src 是空的,因为 iframe 是用 javascript 生成的。 所以选择了 iframe 但内容长度为 0。

【问题讨论】:

mattgemmell.com/2008/12/08/what-have-you-tried 这可能没用,但我不禁想知道为什么您要操作两次嵌套的 iframe 文档...您是怎么到这里的?可能的 XY 问题。 我正在创建一个使用 CKFinder 和 Amazon S3 的 DRM 应用程序。我试图改变的是CKFinder。我对功能进行了大量更改,但现在我需要更改 UI。 (不能用 CSS 更改,因为有多个实例不需要此特定更改) 根据this的回答,你必须在你想使用DOM遍历的每个iframe中链接到jQuery。因此,在您的情况下,uploads 必须包含 &lt;script type="text/javascript" src='js/jquery.min.js"&gt;&lt;/script&gt; 或类似名称。 iframe 盗梦空间! 【参考方案1】:

问题是,您提供的代码不起作用,因为 &lt;iframe&gt; 元素必须具有“src”属性,例如:

<iframe id="uploads" src="http://domain/page.html"></iframe>

使用.contents()获取内容即可:

$('#uploads).contents() 将允许您访问第二个 iframe,但如果该 iframe 在“内部”,http://domain/page.html 将记录 #uploads iframe 已加载。

为了测试我是对的,我创建了 3 个名为 main.html、iframe.html 和 noframe.html 的 html 文件,然后选择了 div#element 就好了:

$('#uploads').contents().find('iframe').contents().find('#element');

由于您需要等待 iframe 加载资源,因此该元素不可用会出现延迟。此外,所有 iframe 都必须在同一个域中。

希望这会有所帮助...

这是我使用的 3 个文件的 html(将“src”属性替换为您的域和 url):

main.html

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>main.html example</title>

    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

    <script>
        $(function () 
            console.log( $('#uploads').contents().find('iframe').contents().find('#element') ); // nothing at first

            setTimeout( function () 
                console.log( $('#uploads').contents().find('iframe').contents().find('#element') ); // wait and you'll have it
            , 2000 );

        );
    </script>
</head>
<body>
    <iframe id="uploads" src="http://192.168.1.70/test/iframe.html"></iframe>
</body>

iframe.html

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>iframe.html example</title>
</head>
<body>
    <iframe src="http://192.168.1.70/test/noframe.html"></iframe>
</body>

noframe.html

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>noframe.html example</title>
</head>
<body>
    <div id="element">some content</div>
</body>

【讨论】:

我的错。实际上,您可以在 iframe 上不使用“src”属性而仅使用 javascript 编写代码:&lt;script&gt; myHTML = '&lt;p&gt;you should write complete and proper html here, including the html, head and body tags&lt;/p&gt;'; myFrame = document.getElementById("uploads").contentDocument; myFrame.open(); myFrame.write(myHTML); myFrame.close(); &lt;/script&gt; 这对我有用。而且我在任何地方都没有身份证。我不得不玩课:) @CarlosCastillo,非常感谢。它也解决了我在引导模式中的 iframe 问题。我正在寻找改变 iframe 内元素的方法,但我的功能总是在 iframe 完全加载之前加载。等待几秒钟是一个解决方案。再次感谢有用的答案,我投票赞成 1+ :)【参考方案2】:

var iframeInner = jQuery(iframe).find('iframe').contents();

var iframeContent = jQuery(iframeInner).contents().find('#element');

iframeInner 包含来自

的元素
<div id="element">other markup goes here</div> 

并且 iframeContent 将查找位于内部的元素

 <div id="element">other markup goes here</div> 

(find 不在当前元素上搜索)这就是它返回 null 的原因。

【讨论】:

【参考方案3】:

嘿,我得到了一些似乎在做你想做的事。它涉及一些肮脏的复制,但有效。你可以找到工作代码here

所以这里是主要的 html 文件:

<!DOCTYPE html>
<html>
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

    <script type="text/javascript">
        $(document).ready(function()
            Iframe = $('#frame1');

            Iframe.on('load', function()
                IframeInner = Iframe.contents().find('iframe');

                IframeInnerClone = IframeInner.clone();

                IframeInnerClone.insertAfter($('#insertIframeAfter')).css(display:'none');

                IframeInnerClone.on('load', function()
                    IframeContents = IframeInner.contents();

                    YourNestedEl = IframeContents.find('div');

                    $('<div>Yeepi! I can even insert stuff!</div>').insertAfter(YourNestedEl)
                );
            );
        );
    </script>
</head>
<body>
    <div id="insertIframeAfter">Hello!!!!</div>
    <iframe id="frame1" src="Test_Iframe.html">

    </iframe>
</body>
</html>

如您所见,加载第一个 iframe 后,我会获取第二个并克隆它。然后我将它重新插入到 dom 中,这样我就可以访问 onload 事件了。加载此内容后,我会从非克隆内容中检索内容(也必须加载,因为它们使用相同的 src)。然后,您可以随心所欲地处理内容。

这是 Test_Iframe.html 文件:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <div>Test_Iframe</div>
    <iframe src="Test_Iframe2.html">
    </iframe>
</body>
</html>

和 Test_Iframe2.html 文件:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <div>I am the second nested iframe</div>
</body>
</html>

【讨论】:

【参考方案4】:

您可能遇到了时间问题。您的 document.ready 推荐可能在第二个 iFrame 加载之前触发。您没有足够的信息来提供更多帮助 - 但如果这似乎是可能的问题,请告诉我们。

【讨论】:

我认为这不是时间问题。一分钟后尝试在单击事件上查找元素仍返回 null。见编辑。【参考方案5】:

您应该对稍后渲染的元素使用 live 方法,例如颜色框、隐藏字段或 iframe

$(".inverter-value").live("change",function() 
     elem = this
    $.ajax(
      url: '/main/invertor_attribute/',
      type: 'POST',
      aysnc: false,
      data: id: $(this).val() ,
      success: function(data)
       // code
      ,
      dataType: 'html'
    );
  );

【讨论】:

【参考方案6】:

我认为到达您的 div 的最佳方式:

var your_element=$('iframe#uploads').children('iframe').children('div#element');

它应该运作良好。

【讨论】:

$('iframe').children('div') 没有找到任何东西。【参考方案7】:

如果浏览器支持 iframe,则 iframe 内的 DOM 来自相应标签的 src 属性。 iframe 标签内的内容用作浏览器不支持 iframe 标签的后备机制。

参考:http://www.w3schools.com/tags/tag_iframe.asp

【讨论】:

【参考方案8】:

我猜你的问题是你的 iframe 中没有加载 jQuery。

最安全的方法是依靠纯基于 DOM 的方法来解析您的内容。

或者,从 jQuery 开始,然后在你的 iframe 中,测试一次 typeof window.jQuery == 'undefined',如果为真,则在其中未启用 jQuery 并回退到基于 DOM 的方法。

【讨论】:

以上是关于嵌套 iframe,又名 iframe Inception的主要内容,如果未能解决你的问题,请参考以下文章

如何检测 iframe(跨域)内的点击?又名防止点击欺诈

一个页面里面嵌套了多个iframe,iframe刷新的问题

iframe嵌套跳转

js查找嵌套iframe的问题

被嵌套页面 如何得到iframe 高度

js怎么控制iframe嵌套页里面文字大小