动态创建具有给定HTML的iframe

2020/11/10 09:22 · javascript ·  · 0评论

我正在尝试从JavaScript创建iframe并用任意HTML填充它,如下所示:

var html = '<body>Foo</body>';
var iframe = document.createElement('iframe');
iframe.src = 'data:text/html;charset=utf-8,' + encodeURI(html);

我希望iframe然后包含一个有效的窗口和文档。但是,事实并非如此:

> console.log(iframe.contentWindow);

空值

自己尝试一下:http : //jsfiddle.net/TrevorBurnham/9k9Pe/

我在俯视什么?

在将元素插入文档中之前,设置javascript中src新创建的iframe不会触发HTML解析器。然后更新HTML,将调用HTML解析器并按预期处理属性。

http://jsfiddle.net/9k9Pe/2/

var iframe = document.createElement('iframe');
var html = '<body>Foo</body>';
iframe.src = 'data:text/html;charset=utf-8,' + encodeURI(html);
document.body.appendChild(iframe);
console.log('iframe.contentWindow =', iframe.contentWindow);

另外,此问题也回答了您的问题,请务必注意,该方法与某些浏览器存在兼容性问题,请参阅@mschr的跨浏览器解决方案。

尽管您src = encodeURI应该工作,但我会采取另一种方式:

var iframe = document.createElement('iframe');
var html = '<body>Foo</body>';
document.body.appendChild(iframe);
iframe.contentWindow.document.open();
iframe.contentWindow.document.write(html);
iframe.contentWindow.document.close();

由于这没有x域限制,并且完全通过iframe手柄完成,因此您稍后可以访问和操纵框架的内容。您需要确定的是,已呈现了内容,该内容(取决于浏览器类型)将在发出.write命令期间/之后开始-close()调用时不必完成

100%兼容的回调方法可以是这种方法:

<html><body onload="parent.myCallbackFunc(this.window)"></body></html>

但是,iframe具有onload事件。这是一种以DOM(js)形式访问内部html的方法:

iframe.onload = function() {
   var div=iframe.contentWindow.document.getElementById('mydiv');
};

感谢您提出的重要问题,这使我不知所措。使用dataURI HTML源时,我发现必须定义一个完整的HTML文档。

参见下面的修改示例。

var html = '<html><head></head><body>Foo</body></html>';
var iframe = document.createElement('iframe');
iframe.src = 'data:text/html;charset=utf-8,' + encodeURI(html);

注意用<html>标签和iframe.src字符串包装的html内容

需要将iframe元素添加到要解析的DOM树中。

document.body.appendChild(iframe);

iframe.contentDocument除非您disable-web-security在浏览器上否则您将无法检查您会收到一条消息

DOMException:无法从“ HTMLIFrameElement”读取“ contentDocument”属性:阻止了起源为“ http:// localhost:7357 ”的框架访问跨域框架。

还有一种创建内容为HTML字符串的iframe的替代方法:srcdoc属性较旧的浏览器不支持此功能(其中包括:Internet Explorer,可能还包括Safari?),但此行为有一个polyfill,您可以在IE中添加条件注释,或使用has.js之类的条件来懒加载它。

我知道这是一个老问题,但我想我将提供一个使用该srcdoc属性的示例,因为该属性现已得到广泛支持,并且这个问题经常被查看。

使用该srcdoc属性,您可以提供嵌入的HTML。src如果支持,它将覆盖属性。src如果不支持,浏览器将退回到该属性。

我还建议使用该sandbox属性对框架中的内容施加额外的限制。如果HTML不是您自己的,这尤其重要。

const iframe = document.createElement('iframe');
const html = '<body>Foo</body>';
iframe.srcdoc = html;
iframe.sandbox = '';
document.body.appendChild(iframe);

如果您需要支持较旧的浏览器,则可以srcdoc从其他答案中查看是否支持并回退到其他方法之一。

function setIframeHTML(iframe, html) {
  if (typeof iframe.srcdoc !== 'undefined') {
    iframe.srcdoc = html;
  } else {
    iframe.sandbox = 'allow-same-origin';
    iframe.contentWindow.document.open();
    iframe.contentWindow.document.write(html);
    iframe.contentWindow.document.close();
  }
}

var iframe = document.createElement('iframe');
iframe.sandbox = '';
var html = '<body>Foo</body>';

document.body.appendChild(iframe);
setIframeHTML(iframe, html);

URL方法仅适用于小型HTML片段。更可靠的方法是从Blob生成对象URL,并将其用作动态iframe的源。

const html = '<html>...</html>';
const iframe = document.createElement('iframe');
const blob = new Blob([html], {type: 'text/html'});
iframe.src = window.URL.createObjectURL(blob);
document.body.appendChild(iframe);

做这个

...
var el = document.getElementById('targetFrame');

var frame_win = getIframeWindow(el);

console.log(frame_win);
...

getIframeWindow在这里定义

function getIframeWindow(iframe_object) {
  var doc;

  if (iframe_object.contentWindow) {
    return iframe_object.contentWindow;
  }

  if (iframe_object.window) {
    return iframe_object.window;
  } 

  if (!doc && iframe_object.contentDocument) {
    doc = iframe_object.contentDocument;
  } 

  if (!doc && iframe_object.document) {
    doc = iframe_object.document;
  }

  if (doc && doc.defaultView) {
   return doc.defaultView;
  }

  if (doc && doc.parentWindow) {
    return doc.parentWindow;
  }

  return undefined;
}
本文地址:http://javascript.askforanswer.com/dongtaichuangjianjuyougeidinghtmldeiframe.html
文章标签: ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!