在我粘贴任何代码之前,这是场景:
- 我有一个使用 JavaScript 创建一个空 iframe 的 HTML 文档
- JavaScript 创建一个函数并将对该函数的引用附加到 iframe 的文档对象(
doc.open()
用于获取对文档的引用) onload
然后将该函数作为iframe 文档的处理程序附加(通过写入<body onload="...">
iframe.
现在让我感到困惑的是,onload 处理程序中的全局(窗口)和文档对象(在它运行时)与通过脚本节点添加的 JavaScript 运行的相同对象不同。
这是HTML:
<!doctype html>
<html>
<head>
<script>
(function(){
var dom,doc,where,iframe;
iframe = document.createElement('iframe');
iframe.src="javascript:false";
where = document.getElementsByTagName('script')[0];
where.parentNode.insertBefore(iframe, where);
doc = iframe.contentWindow.document;
var _doc = document;
doc.open()._l=function() {
// the window object should be the one that doc is inside
window.vanishing_global=new Date().getTime();
var js = this.createElement("script");
js.src = 'test-vanishing-global.js?' + window.vanishing_global;
window.name="foobar";
this.foobar="foobar:" + Math.random();
document.foobar="barfoo:" + Math.random();
// `this` should be the document object, but it's not
console.log("this == document: %s", this == document);
console.log("this == doc: %s", this == doc);
// the next two lines added based on @Ian's comment below
console.log("_doc == document: %s", _doc == document);
console.log("_doc == doc: %s", _doc == doc);
console.log("name: " + window.name + "\n" + "window.vanishing_global: " + window.vanishing_global + "\ntypeof window.vanishing_global: " + typeof window.vanishing_global + "\ndocument.foobar: " + document.foobar);
this.body.appendChild(js);
};
doc.write('<body onload="document._l();"></body>');
doc.close();
})();
</script>
</head>
<body>
</body>
</html>
这是test-vanishing-global.js
:
console.log("name: " + window.name + "\n" + "window.vanishing_global: " + window.vanishing_global + "\ntypeof window.vanishing_global: " + typeof window.vanishing_global + "\ndocument.foobar: " + document.foobar);
指示:
将这两个文件放入一个目录,然后在浏览器中打开 HTML(在最新的 Chrome 和 Firefox 中测试,两者结果相同)。
这是我得到的输出:
this == document: false
this == doc: true
_doc == document: true
_doc == doc: false
name: foobar
window.vanishing_global: 1366037771608
typeof window.vanishing_global: number
document.foobar: barfoo:0.9013048021588475
name:
window.vanishing_global: undefined
typeof window.vanishing_global: undefined
document.foobar: foobar:0.5015988759696484
处理程序内的this
对象应该是文档对象。它是一个文档对象,但与它在其中运行的文档不同(它也与父文档不同)。处理程序中的 window 对象也与页面中加载的 JavaScript 中运行的 window 对象不同。
所以最后我的问题:
有谁知道发生了什么,以及如何获得对实际窗口对象的引用,或者至少从同一个全局上下文中声明和引用全局变量?
脚注:
此 iframe 不存在跨域问题,因为它们位于同一域中。如果有人设置 会出现问题document.domain
,但在此示例代码中没有这样做。