嵌套 iframe,又名 iframe Inception

IT技术 javascript jquery iframe
2021-03-10 15:17:34

使用 jQuery 我试图访问 div id="element"。

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

所有 iframe 都在同一个域中,没有 www / 非 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。

6个回答

问题是,您提供的代码将不起作用,因为该<iframe>元素必须具有“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(用您的域和 url 替换“src”属性):

主文件

<!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>
这对我有用。而且我在任何地方都没有身份证。我不得不上课:)
2021-04-18 15:17:34
@CarlosCastillo,非常感谢。它也解决了我在引导模式中使用 iframe 的问题。我正在寻找更改 iframe 内元素的方法,但我的功能总是在 iframe 完全加载之前加载。等待几秒钟是一个解决方案。再次感谢有用的答案,我投了 1+:)
2021-04-18 15:17:34
我的错。您实际上可以在 iframe 上不使用“src”属性并仅使用 javascript 编写代码: <script> myHTML = '<p>you should write complete and proper html here, including the html, head and body tags</p>'; myFrame = document.getElementById("uploads").contentDocument; myFrame.open(); myFrame.write(myHTML); myFrame.close(); </script>
2021-05-14 15:17:34

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 的原因。

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

所以这里是主要的 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>

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

我不认为这是时间问题。一分钟后尝试在单击事件上查找元素仍然返回 null。见编辑。
2021-05-16 15:17:34

您应该对稍后渲染的元素使用 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'
    });
  });