我迫切需要一些帮助。
我创建了一个< 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
答案 0 :(得分:11)
如果我把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')
,则bar
仅在IE中foo
之前编写。如果我添加了bar
和close
调用,则IE崩溃。
总而言之,在document.write
编写的文档中使用document.write
存在深层问题!尽可能避免使用它。 document.open
可以是从父文档填充iframe的有用方法,但您不应该在子文档中真正需要它,您可以在自己使用DOM方法。
答案 1 :(得分:4)
正如大多数人已经介绍的那样,IE在尝试做一些简单的事情时会遇到严重问题:
var doc = window.frames['your_frame'].document;
doc.open();
doc.write('<body><script src="external_resource.js"><\/script>');
doc.close();
经过详尽的搜索后,我发现这个this write-up建议使用javascript:URI方案将内容插入到iframe文档中。我个人在当前版本的FF,Chrome和&amp ;;中测试了这个解决方案。 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的字符限制问题(因为它比其他所有浏览器都要小),但是值得研究那些遇到类似问题的人。
答案 2 :(得分:2)
根本问题是IE中的你无法做到
iframe_document.open();
iframe_document.write('<script src="foo.js"><\/script>');
iframe_document.close();
在iframe上调用document.close()之后,IE似乎暂停了所有javascript执行。 js线程运行document.close(),而foo.js的http请求未完成,因此文件已加载但从未执行过。
我没有找到任何方法让父页面知道在iframe中执行的脚本已完全完成。一个解决办法就是让foo.js负责调用document.close()本身 - 不是很愉快,但是如果你不介意改变被调用的脚本,它就可以解决问题。
注意:你不能将document.write('document.close()')直接导入iframe: 会导致IE难以挂起。但是setTimeout(function(){document.close()},0)似乎是免疫的 - 就像加载的脚本中的document.close()有时一样。啊。
答案 3 :(得分:1)
您应该使用"src"
属性加载iframe的内容:iframe的正文由不支持iframe的浏览器使用,以显示替代消息。相反,您将在iframe中注入一个完整的内联html文档,而某些浏览器则不喜欢它。
更多信息here。
如果您想从主文档向iframe发送消息,可以在John Resig's blog上找到一个很好的教程。
答案 4 :(得分:0)
会像以下一样简单:
function render(data) {
document.body.innerHTML = data;
}
解决你的问题?适用于IE8 / Win7。
答案 5 :(得分:0)
这很奇怪,迈克尔克莱伯错了:所有的警报都很好,所以问题不在于脚本没有执行。它确实执行。
观察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();
});