如何使用iframe或shadow dom创建跨浏览器子文档?

我想用JavaScript创建一个完全封装的子文档,它有自己的 ,styles,html和js。 基本上是阴影dom或iframe,但没有src属性。

虽然我喜欢影子dom的想法,但它的支持率非常低,因此尚未准备好迎接黄金时段。

所以我一直致力于创建一个iframe,但一路上都遇到了各种各样的障碍。 这是一个jsFiddle,展示了我的各种尝试。

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

 $('body').append(''); 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 = $('').append(iframe3Contents); 

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

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

 var iframeHtml; giveMeIframe = function() { var iframeContents; if (iframeHtml) { return iframeHtml; } else { $('body').append(''); iframeContents = $('#iframeGenerator').contents(); iframeHtml = $(''); iframeHtml.append(iframeContents); $('#iframeGenerator').remove(); return iframeHtml; } } 

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

为了将来参考任何绊倒这个问题的人,你可以得到这样的封装:

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

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

在jsfiddle示例中,注意一切只有在添加到DOM之后才有效。

我和你的小提琴一起玩,并且能够让它运转起来。 我正在使用无缝(仅限Chrome)使其行为更符合您的要求,并且我有其他浏览器的CSS后备。

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

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

JS

 var styles = ''; var html = '
PINK!
'; // 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; }