gpt4 book ai didi

javascript - 如何在从父窗口创建的 iframe 加载处理程序中获取对 iframe 窗口对象的引用

转载 作者:IT王子 更新时间:2023-10-29 03:00:29 25 4
gpt4 key购买 nike

在我粘贴任何代码之前,场景如下:

  1. 我有一个使用 JavaScript 创建空 iframe 的 HTML 文档
  2. JavaScript 创建一个函数并将对该函数的引用附加到 iframe 的文档对象(使用 doc.open() 获取对文档的引用)
  3. 然后将函数附加为 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处理程序中的对象应该是文档对象。它一个文档对象,但与它在其中运行的文档不是同一个文档对象(它也不同于父文档)。处理程序中的窗口对象也不同于在页面中加载的 JavaScript 中运行的窗口对象。

最后我的问题是:

有谁知道发生了什么,我如何才能获得对实际窗口对象的引用,或者至少从相同的全局上下文中声明和引用全局变量?

脚注:

此 iframe 不存在跨域问题,因为它们位于同一域中。如果有人设置 document.domain 就会出现问题,但此示例代码中并未这样做。

最佳答案

您要在父页面中声明所有内容。所以引用 windowdocument是父页面的。如果你想对 iframe 做些什么的,使用 iframe || iframe.contentWindow访问其 window , 和 iframe.contentDocument || iframe.contentWindow.document访问其 document .

有一个词可以描述正在发生的事情,可能是“词法范围”:What is lexical scope?

作用域的唯一上下文是this。在您的示例中,该方法的所有者是 doc ,这是 iframedocument .除此之外,在此函数中访问的任何使用已知对象的对象都是父对象的(如果未在函数中声明)。如果函数声明在不同的地方,但它是在父页面中声明的,那就另当别论了。

我会这样写:

(function () {
var dom, win, doc, where, iframe;

iframe = document.createElement('iframe');
iframe.src = "javascript:false";

where = document.getElementsByTagName('script')[0];
where.parentNode.insertBefore(iframe, where);

win = iframe.contentWindow || iframe;
doc = iframe.contentDocument || iframe.contentWindow.document;

doc.open();
doc._l = (function (w, d) {
return function () {
w.vanishing_global = new Date().getTime();

var js = d.createElement("script");
js.src = 'test-vanishing-global.js?' + w.vanishing_global;

w.name = "foobar";
d.foobar = "foobar:" + Math.random();
d.foobar = "barfoo:" + Math.random();
d.body.appendChild(js);
};
})(win, doc);
doc.write('<body onload="document._l();"></body>');
doc.close();
})();

win 的别名和 doc作为wd不是必需的,它可能会因为对范围的误解而减少混淆。这样,它们就是参数,您必须引用它们才能访问 iframe的东西。如果你想访问 parent 的,你仍然使用windowdocument .

我不确定向 document 添加方法意味着什么(在本例中为 doc),但设置 _l 可能更有意义win 上的方法.这样,事情可以在没有前缀的情况下运行......例如<body onload="_l();"></body>

关于javascript - 如何在从父窗口创建的 iframe 加载处理程序中获取对 iframe 窗口对象的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16018598/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com