19

我想在 JavaScript 中创建一个完全封装的子文档,它有自己的<head><body>、 样式、 html 和 js。基本上是一个影子 dom 或 iframe,但没有 src 属性。

虽然我喜欢 shadow dom 的想法,但它的支持率很低,因此还没有准备好迎接黄金时段。

所以我一直在努力创建一个 iframe,但在此过程中遇到了各种障碍。这是一个 jsFiddle,展示了我的各种尝试。

iframe 不能存在于 dom 中。这部分很关键。澄清一下,如果它暂时存在于dom中是可以的,但它必须能够被提取并只存在于JS中。

$('body').append('<iframe id="iframeGenerator" />');
var iframe3 = $('#iframeGenerator');
var iframe3Contents = iframe3.contents();
$('#iframeGenerator').remove();
var head = iframe3.contents().find('head');

亲爱的,我们有头了

console.log(head.length);

但内容是什么样的?

console.log(iframe3Contents.get(0));

它是一个文档,但不在元素内部,所以让我们尝试将它放在 dom 或另一个元素内部? 以下两种尝试都不起作用,因为选择器没有上下文或其他东西......

$('body').append(iframe3Contents);
var generatedIframe = $('<iframe />').append(iframe3Contents);

我希望能够在不向 dom 附加任何内容的情况下创建 iframe / subdocuemnt ...但如果必须的话,我仍然希望能够随后将其从 dom 中删除并在 js 中进一步管理它。

我有这个不起作用的小功能,但说明了我想要创建的 iframe 或子文档生成器的类型

var iframeHtml;
giveMeIframe = function() {
  var iframeContents;
  if (iframeHtml) {
    return iframeHtml;
  } else {
    $('body').append('<iframe id="iframeGenerator" style="display: none" />');
    iframeContents = $('#iframeGenerator').contents();
    iframeHtml = $('<iframe />');
    iframeHtml.append(iframeContents);
    $('#iframeGenerator').remove();
    return iframeHtml;
  }
}
4

2 回答 2

4

要从框架访问信息(或写入框架),它必须在 DOM 中。它可以被隐藏,但它仍然必须存在于框架对象中。JQuery 正在通过框架对象访问 iFrame,当从 dom 中删除时,它会从框架对象中删除

为了将来参考任何偶然发现这个问题的人,您可以像这样获得封装:

$('#iframeGenerator2').contents().find('html').html(frame2HTML);

这是一个例子:http: //jsfiddle.net/yP34y/4/

在 jsfiddle 示例中,请注意只有在将其添加到 DOM 后才能正常工作。

于 2014-02-16T20:49:23.107 回答
0

我玩弄了你的小提琴并且能够让它工作。我正在使用无缝(仅 Chrome)使其行为更符合您正在寻找的内容,并且我为其他浏览器提供了 CSS 后备。

请注意,在开始编辑其内容(添加样式和正文)之前,需要将 iframe 添加到 DOM。之后可以删除document.body.removeChild(iframe);

你仍然可以做很多事情来让它的行为与 shadow DOM 元素非常相似,这个演示文稿将帮助你了解无缝 iframe:未来,今天!

JS

var styles = '<style> .pink { color: pink; width: 100px; height: 100px; } body{background-color:#eee;}</style>';

var html = '<div class="pink">PINK!</div>';

// create iframe
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);

//add head and body
iframe.contentDocument.open();
iframe.contentDocument.write(styles);
iframe.contentDocument.write(html);
iframe.contentDocument.close();
iframe.setAttribute('seamless', 'seamless');

//check everything
console.log(iframe);
var head = $(iframe).contents().find('head')[0];
console.log(head);
var body = $(iframe).contents().find('body')[0];
console.log(body);

//remove from DOM
//document.body.removeChild(iframe);

CSS

iframe[seamless]{
    background-color: transparent;
    border: 0px none transparent;
    padding: 0px;
    overflow: hidden;
}
于 2014-02-21T14:25:30.147 回答