简体   繁体   English

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

[英]How to create a cross-browser sub document with iframe or shadow dom?

I want to create a totally encapsulated sub-document in JavaScript, with its own <head> , <body> , styles, html, and js. 我想在JavaScript中创建一个完全封装的子文档,它有自己的<head><body> ,styles,html和js。 Basically a shadow dom, or an iframe, but without an src attribute. 基本上是阴影dom或iframe,但没有src属性。

Though I love the idea of shadow dom, its support is very low, and thus is not ready for prime time. 虽然我喜欢影子dom的想法,但它的支持率非常低,因此尚未准备好迎接黄金时段。

So I have been working on creating an iframe, but have been hitting various road-blocks along the way. 所以我一直在努力创建一个iframe,但是一路上都遇到了各种各样的障碍。 Here is a jsFiddle demonstrating my various attempts. 这是一个jsFiddle,展示了我的各种尝试。

The iframe cannot exist in the dom. iframe不能存在于dom中。 This part is critical. 这部分很关键。 To clarify, it is okay if it momentarily exists in the dom, but it must be able to be extracted and exist only in JS. 为了澄清,如果它暂时存在于dom中是可以的,但它必须能够被提取并且仅存在于JS中。

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

sweet, we have the head 甜蜜,我们有头脑

console.log(head.length);

but what do the contents look like? 但内容是什么样的?

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

It is a document, but not inside of an element so lets try to put it in the dom or inside of another element? 它是一个文档,但不在元素内部,所以让我们尝试将它放在dom或另一个元素的内部? both of the following attempts don't work because the selector has no context or something ... 以下两种尝试都不起作用,因为选择器没有上下文或某些东西......

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

I would love to be able to create the iframe / subdocuemnt without appending anything to the dom... but if I must, I would still like to be able to subsequently remove it from the dom and manage it further in js. 我希望能够创建iframe / subdocuemnt而不向dom添加任何内容......但如果我必须,我仍然希望能够随后将其从dom中删除并在js中进一步管理它。

I have this little function, which doesn't work, but illustrates the kind of iframe or subdocument generator I would like to create 我有这个小功能,它不起作用,但说明了我想要创建的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;
  }
}

To access info from the frame (or write to the frame), it must be in the DOM. 要从帧中访问信息(或写入帧),它必须位于DOM中。 It can be hidden, but it still must live in the frames object. 它可以隐藏,但它仍然必须存在于框架对象中。 JQuery is accessing the iFrame through the frames object and when removed from the dom, it's removed from the frames object JQuery通过frames对象访问iFrame,当从dom中删除时,它从frame对象中删除

For future reference to anyone stumbling across this question, you can get the encapsulation like so: 为了将来参考任何绊倒这个问题的人,你可以得到这样的封装:

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

Here's an example: http://jsfiddle.net/yP34y/4/ 这是一个例子: http//jsfiddle.net/yP34y/4/

In the jsfiddle example, notice everything only works after it's been added to the DOM. 在jsfiddle示例中,注意一切只有在添加到DOM后才能工作。

I played around with your fiddle and was able to get it working. 我和你的小提琴一起玩,并且能够让它运转起来。 I'm using seamless (only Chrome) to make it behave more in line with what you're looking for and I have a CSS fallback for other browsers. 我正在使用无缝(仅限Chrome)使其行为更符合您的要求,并且我有其他浏览器的CSS后备。

As a note, the iframe needs to be added to the DOM before you start editing it's contents(adding styles and body). 需要注意的是,在开始编辑iframe的内容(添加样式和正文)之前,需要将iframe添加到DOM中。 You can remove afterwards document.body.removeChild(iframe); 您可以删除document.body.removeChild(iframe); .

There is still a lot you can do to make it behave very similarly to a shadow DOM element, this presentation will help you out Seamless iframes: The future, today! 你可以做很多事情来使它的行为与shadow DOM元素非常相似,这个演示文稿将帮助你解决无缝的iframe:未来,今天!

JS 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 CSS

iframe[seamless]{
    background-color: transparent;
    border: 0px none transparent;
    padding: 0px;
    overflow: hidden;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM