使用Javascript或jQuery将元素写入子iframe

55

我有这样的一个东西:

<!doctype html>
<html>
  <body>
     <iframe id="someFrame"></iframe>
  </body>
</html>

我希望使用 jQuery 编写元素,使得最终的 HTML 等价于以下代码:

<!doctype html>
<html>
  <body>
    <iframe id="someFrame">
      <!-- inside the iframe's content -->
      <!-- <html><body>  -->
      <div>A</div>
      <div>B</div>
      <div>C</div>
      <!-- </body></html> -->
    </iframe>
  </body>
</html>

另外,任何纯JavaScript都可以。

谢谢。

编辑:经过更多的研究,似乎我正在寻找一个IE版本的iframe的contentDocument属性。 "contentDocument"是一个W3C标准,FF支持它,但IE不支持。(意料之中的惊喜)

5个回答

97

你可以同时进行两种操作,只需要选择不同的目标:

var ifrm = document.getElementById('myIframe');
ifrm = ifrm.contentWindow || ifrm.contentDocument.document || ifrm.contentDocument;
ifrm.document.open();
ifrm.document.write('Hello World!');
ifrm.document.close();

2
aha - contentWindow。我发现打开和关闭是开始使用jquery的必要条件... - Jeff Meatball Yang
这种方法不再可行。我收到了一个JS错误,说是“Unsafe JavaScript attempt to access frame with URL "URL1" from frame with URL "URL2". Domains, protocols and ports must match.”(尝试从URL2的框架中访问URL1的框架是不安全的,域名、协议和端口必须匹配)。下面给出的桥接方法可以正常工作。 - kay am see
1
我知道这是一个旧的线程,但在什么情况下你会有ifrm.contentDocument.document.document - ars265
为什么不能直接在 iframe 的 body 中编写,而只能使用这种 hack 方法? - Kiechlus
没有close()语句,所有接下来的JS都不会被执行,因此使用try finally块是有意义的。 谢谢。这个答案帮助我找出了我的页面出了什么问题。 - user2932688
这在Firefox中似乎不起作用。 - chovy

36

经过一些研究,以及Mike的协作回答,我找到了这个解决方案:

  var d = $("#someFrame")[0].contentWindow.document; // contentWindow works in IE7 and FF
  d.open(); d.close(); // must open and close document object to start using it!

  // now start doing normal jQuery:
  $("body", d).append("<div>A</div><div>B</div><div>C</div>");

13
有趣。您知道为什么需要进行开闭操作吗? - Nosredna
太棒了!谢谢Jeff! - Metropolis
这是一个完美的解决方案,解决了我在codemirrors editor.getValue()中遇到的问题! - hannacreed

12

HTMLIFrameElement: srcdoc 属性

HTMLIFrameElementsrcdoc 属性指定页面的内容。

document.querySelector("button").addEventListener("click", function() {
  document.querySelector("iframe").srcdoc = "Hello, world!";
});
<iframe></iframe>
<button>Write</button>


太好了,JSFiddle非常有帮助。谢谢! - dotancohen

7
我在这里冒险猜测,到目前为止提出的答案是不可能的。如果这个iframe实际上有一个src="somepage.html"(你应该已经指出了,如果没有,使用iframe的意义是什么?),那么我认为Jquery无法直接在所有浏览器中跨框架操作html。基于我对这种事情的经验,包含页面不能直接从iframe页面调用函数或进行任何类型的Javascript联系。你的“somepage.html”(加载在iframe中的页面)需要完成两件事:传递一些对象到包含页面,可以用作桥梁,并具有一个设置所需HTML的函数。例如,somepage.html可能如下所示:
<!doctype html>
<html>
<head>
<script src="jquery.js">
</script>
<script language=JavaScript>
<!--//
    var bridge={
        setHtml:function(htm) {
            document.body.innerHTML=htm;
        }
    }

    $(function() { parent.setBridge(bridge); });

//--></script>
</head>
<body></body>
</html>

包含此内容的页面可能如下所示:

<!doctype html>
<html>
<head>
<script src="jquery.js">
</script>
<script language=JavaScript>
<!--//
var bridge;
var setBridge=function(br) {
    bridge=br;
    bridge.setHtml("<div>A</div><div>B</div><div>C</div>");
    }
//-->
</script>
</head>
<body><iframe src="somepage.html"></iframe></body>
</html>

这可能看起来有点复杂,但它可以适用于多个方向,并且应该在至少IE、FF、Chrome上运行,可能也适用于Safari和Opera...

谢谢您的回答 - 但我想使用此iframe来像富文本编辑器一样组合HTML。我不设置src属性,因为它会被清除并从“顶部”窗口重新组合。另外 - 我认为必须有可能访问子DOM - 请参见我在OP中的编辑。 - Jeff Meatball Yang
你需要使用iframe而不是div的原因是什么?看起来div会更容易且不太可能在不同浏览器中出现问题。 - Jeremy Wall
1
原来如此,这是有原因的。您需要放置外部JavaScript,但不希望它损坏您的页面。但是您还需要引用者与您的顶级域匹配。这是在页面上放置广告的最常见方法:<iframe></iframe> + document.write('<script tags go here>')。 - KateYoak

1
我发现这是跨浏览器兼容的...有一点交叉之前的答案和一些我的试错。 :)
我正在使用它来下载报告,或者如果出现错误(消息),则在iFrame中显示。大多数用户可能会隐藏iFrame,我正在将其用于多功能。
问题是每次单击报告下载按钮时,我都必须清除iFrame的内容 - 用户可以更改参数,如果没有结果,则会在iFrame中显示为消息。 如果有结果,则iFrame保持为空 - 因为下面的代码已经清除了它,而window.open(...)方法生成一个Content-Disposition: attachment;filename=...文档。
var $frm = $("#reportIFrame");
var $doc = $frm[0].contentWindow ? $frm[0].contentWindow.document : $frm[0].contentDocument;
var $body = $($doc.body);
$body.html(''); // clear iFrame contents <- I'm using this...
$body.append('<i>Writing into the iFrame...</i>'); // use this to write something into the iFrame
window.open(Module.PATH + 'php/getReport.php' + Report.queryData, 'reportIFrame');

我没有支持contentDocument的浏览器,但我已经这样编码了,所以我不会更改它。也许有人有旧的浏览器并且可以发布兼容性确认/问题?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接