我正在尝试从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解析器并按预期处理属性。
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;
}
文章标签:iframe , javascript
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!
评论已关闭!