![](/img/trans.png)
[英]Using window.open, document.open, and document.write to display XML (XML rendering gone)
[英]Why won't this JavaScript (using document.open and document.write) work in Internet Explorer or Opera?
我迫切需要一些帮助。
我创建了一个非常平行的<script>,并重现了我在其他地方写过的另一个更复杂的<script>的问题。
这是它的作用:
涉及的三个文件是:
这一切都适用于Firefox,Safari和Chrome。 它崩溃的地方是Internet Explorer和Opera。 会发生什么是main.js中的render()函数执行,并且触发了所有三个警报,但<iframe>中的文档没有被覆盖。 我无法分辨出正在创建或写入的文档,或者根本不是。
如果我在render()函数的开头添加调试代码(如console.log(document)),那么工作浏览器似乎可以获得现有<iframe>文档的句柄并列出下面包含的属性。 Internet Explorer似乎也可以找到某种文档。 我只是不知道为什么不让我覆盖它。
这可能是范围问题吗? 也许我不正确地使用document.write(),document.open()或document.close()方法,Firefox和其他一些浏览器只是让我逃脱它?
一个可能的线索:如果我把render()函数的内容拿出来(即,只是把它们放在main.js中的load()之后),这样可以正常工作。 这告诉我,我不是如何使用document.open()等,但是在执行callback()函数时,文档对象不可用,或者超出了范围,或类似的东西。
这让我非常难过,这是一个非常重要的项目,即将到期。 如果它让我摆脱这种干扰,我不会超越黑客或解决方法。 任何帮助或见解都将非常感激!
console.log()的文档属性列表:
ATTRIBUTE_NODE: 2 CDATA_SECTION_NODE: 4 COMMENT_NODE: 8 DOCUMENT_FRAGMENT_NODE: 11 DOCUMENT_NODE: 9 DOCUMENT_POSITION_CONTAINED_BY: 16 DOCUMENT_POSITION_CONTAINS: 8 DOCUMENT_POSITION_DISCONNECTED: 1 DOCUMENT_POSITION_FOLLOWING: 4 DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 32 DOCUMENT_POSITION_PRECEDING: 2 DOCUMENT_TYPE_NODE: 10 ELEMENT_NODE: 1 ENTITY_NODE: 6 ENTITY_REFERENCE_NODE: 5 NOTATION_NODE: 12 PROCESSING_INSTRUCTION_NODE: 7 TEXT_NODE: 3 URL: "http://localhost/projects/test/ajax_loader/document_write/index.html" activeElement: HTMLBodyElement addEventListener: function addEventListener() { adoptNode: function adoptNode() { alinkColor: "" all: HTMLCollection anchors: HTMLCollection appendChild: function appendChild() { applets: HTMLCollection attributes: null baseURI: "http://localhost/projects/test/ajax_loader/document_write/index.html" bgColor: "" body: HTMLBodyElement captureEvents: function captureEvents() { characterSet: "UTF-8" charset: "UTF-8" childNodes: NodeList clear: function clear() { cloneNode: function cloneNode() { close: function close() { compareDocumentPosition: function compareDocumentPosition() { compatMode: "BackCompat" cookie: "__gads=ID=62bb88ab20ac9451:T=1256683145:S=ALNI_Mbso-nFjAvRzYhCSwhiuaDh84G8CA" createAttribute: function createAttribute() { createAttributeNS: function createAttributeNS() { createCDATASection: function createCDATASection() { createComment: function createComment() { createDocumentFragment: function createDocumentFragment() { createElement: function createElement() { createElementNS: function createElementNS() { createEntityReference: function createEntityReference() { createEvent: function createEvent() { createExpression: function createExpression() { createNSResolver: function createNSResolver() { createNodeIterator: function createNodeIterator() { createProcessingInstruction: function createProcessingInstruction() { createRange: function createRange() { createTextNode: function createTextNode() { createTreeWalker: function createTreeWalker() { defaultCharset: "iso-8859-1" defaultView: DOMWindow designMode: "off" dir: "" dispatchEvent: function dispatchEvent() { doctype: null documentElement: HTMLHtmlElement documentURI: "http://localhost/projects/test/ajax_loader/document_write/index.html" domain: "localhost" elementFromPoint: function elementFromPoint() { embeds: HTMLCollection evaluate: function evaluate() { execCommand: function execCommand() { fgColor: "" firstChild: HTMLHtmlElement forms: HTMLCollection getCSSCanvasContext: function getCSSCanvasContext() { getElementById: function getElementById() { getElementsByClassName: function getElementsByClassName() { getElementsByName: function getElementsByName() { getElementsByTagName: function getElementsByTagName() { getElementsByTagNameNS: function getElementsByTagNameNS() { getOverrideStyle: function getOverrideStyle() { getSelection: function getSelection() { hasAttributes: function hasAttributes() { hasChildNodes: function hasChildNodes() { hasFocus: function hasFocus() { height: 150 images: HTMLCollection implementation: DOMImplementation importNode: function importNode() { inputEncoding: "UTF-8" insertBefore: function insertBefore() { isDefaultNamespace: function isDefaultNamespace() { isEqualNode: function isEqualNode() { isSameNode: function isSameNode() { isSupported: function isSupported() { jQuery1258269389622: 2 lastChild: HTMLHtmlElement lastModified: "" linkColor: "" links: HTMLCollection localName: null location: Location lookupNamespaceURI: function lookupNamespaceURI() { lookupPrefix: function lookupPrefix() { namespaceURI: null nextSibling: null nodeName: "#document" nodeType: 9 nodeValue: null normalize: function normalize() { open: function open() { ownerDocument: null parentElement: null parentNode: null plugins: HTMLCollection preferredStylesheetSet: null prefix: null previousSibling: null queryCommandEnabled: function queryCommandEnabled() { queryCommandIndeterm: function queryCommandIndeterm() { queryCommandState: function queryCommandState() { queryCommandSupported: function queryCommandSupported() { queryCommandValue: function queryCommandValue() { querySelector: function querySelector() { querySelectorAll: function querySelectorAll() { readyState: "complete" referrer: "http://localhost/projects/test/ajax_loader/document_write/index.html" releaseEvents: function releaseEvents() { removeChild: function removeChild() { removeEventListener: function removeEventListener() { replaceChild: function replaceChild() { scripts: HTMLCollection selectedStylesheetSet: null styleSheets: StyleSheetList textContent: null title: " Page" vlinkColor: "" width: 300 write: function write() { writeln: function writeln() { xmlEncoding: null xmlStandalone: false xmlVersion: null
如果我把render()函数的内容拿出来(也就是说,只需将它们放在main.js中的load()之后),这样就可以了。
在IE8中不适合我。 如果我完全丢失了AJAX调用并且只是在main.js中调用render()
,我会得到相同的结果。 事实上,即使我用以下内容替换整个main.js:
document.write('hello!');
无论是否打开文件,你好都不会出现!
如果我在main.js的render
调用中放置任何超时(甚至0),它就可以工作。 另一方面,父文档的超时似乎没有做任何事情。
这种极端的怪异是由jQuery使用临时插入的<script>
标记来执行jsonp.js中返回的代码引起的。 如果你只是在返回值上调用eval
而不是让jQuery执行它,它就可以正常工作。
我发现缩小hello示例的相关问题由index.html证明:
<body>
<iframe name="foo"></iframe>
<script>
var idoc= frames['foo'].document;
idoc.open();
idoc.write('<body><script src="main.js"><\/script>');
idoc.close();
</script>
与main.js包含:
document.write('foo');
没有foo写的。 (另一方面,内联脚本很好。)
如果省略了idoc.close
,它就可以了。 如果添加了额外的idoc.write('bar')
,则仅在IE中的foo
之前编写该bar
。 如果我添加了bar
和close
调用,IE崩溃了。
总而言之,在document.write编写的document.write
使用document.write
存在很大的问题 ! 尽可能避免使用它。 document.open
可以是一种从父文档填充iframe的有用方法,但是你不应该在子文档中真正需要它,在那里你可以自己使用DOM方法。
正如大多数人已经介绍过的那样,IE在尝试做一些简单的事情时会遇到严重问题:
var doc = window.frames['your_frame'].document;
doc.open();
doc.write('<body><script src="external_resource.js"><\/script>');
doc.close();
详尽的搜索后,我发现这这写这表明使用JavaScript:URI方案插入内容到IFRAME文档。 我亲自在当前版本的FF,Chrome和Safari以及IE 7/8/9/10中测试了这个解决方案。
借用他的例子,下面的代码将取代我上面的例子,可以用来实现你的目标:
var iframe = window.frames['your_frame'];
var content = '<body><script src="external_resource.js"><\/script>';
iframe.contentWindow.contents = content;
iframe.src = 'javascript:window["contents"]';
我听说它说老版本的Safari不能很好地处理javascript:URI方案,但是我找不到确认的方法,因为使用Safari的每个人似乎都经常升级。 我也不知道这是否会影响IE中URI的字符限制问题(因为它比其他所有浏览器都要小),但是值得研究那些遭遇类似问题的人。
根本问题是在IE中你做不到
iframe_document.open();
iframe_document.write('<script src="foo.js"><\/script>');
iframe_document.close();
一旦在iframe上调用了document.close(),IE似乎就会暂停所有javascript执行。 当foo.js的http请求未完成时,js线程运行document.close(),因此文件已加载但从未执行过。
我没有找到任何方式让父页面知道在iframe中执行的脚本已完全完成。 一个解决方法是让foo.js负责调用document.close()本身 - 不是很愉快,但是如果你不介意改变被调用的脚本,那就可以了。
注意:你不能直接将document.write('document.close()')放入iframe: 这会导致IE难以挂起。 但是setTimeout(function(){document.close()},0)似乎是免疫的 - 有时加载脚本中的document.close() 也是如此 。 啊。
您应该使用"src"
属性加载iframe的内容:iframe的正文由不支持它的浏览器使用以显示替代消息。 相反,您将在iframe中注入一个完整的内联html文档,而某些浏览器则不喜欢它。 更多信息在这里 。
如果你想从主文档向iframe发送消息,可以在John Resig的博客上找到一个很好的教程。
会像这样简单:
function render(data) {
document.body.innerHTML = data;
}
解决你的问题? 适用于IE8 / Win7。
这很奇怪,迈克尔克莱伯错了:所有警报都很好,所以问题不在于脚本没有执行。 它确实执行。
观察main.js的以下更改:
$(document).ready(function() {
// note that render() has to be moved into the window scope
window.render = function(data) {
document.open();
alert('opened');
document.write(data);
alert('written');
document.close();
alert('closed');
}
function load() {
$.ajax({
url: 'jsonp.js',
dataType: 'script'
});
}
window.callback = function(data) {
// does not work
render(data);
// works
window.data = data;
var t = setTimeout("render(data)", 0);
}
load();
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.