如何获取对iframe的窗口对象的引用iframe的onload处理程序从父窗口创建 [英] How to get a reference to an iframe's window object inside iframe's onload handler created from parent window

查看:130
本文介绍了如何获取对iframe的窗口对象的引用iframe的onload处理程序从父窗口创建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




  1. 我有一个HTML文档,使用JavaScript创建一个空的iframe

  2. JavaScript创建一个函数,并将该函数的引用附加到iframe的文档对象(使用 doc.open()获取引用文档)

  3. 然后,该函数作为iframe文档的 onload 处理程序附加(通过写入< ; 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;

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

doc = iframe.contentWindow.document;

var _doc = document;

doc.open()._ l = function(){
//窗口对象应该是文档在
中的一个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`应该是文档对象,但它不是
console.log(this == document:%s,this == document);
console.log(this == doc:%s,this == doc);

//根据@ Ian的评论添加下一行两行
console.log(_ doc == document:%s,_doc == document);
console.log(_ doc == doc:%s,_doc == doc);

console.log(name:+ window.name +\\\
+window.vanishing_global:+ window.vanishing_global +\\\
typeof window.vanishing_global:+ typeof window .vanishing_global +\\\
document.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 +\\\
+window.vanishing_global: + window.vanishing_global +\\\
typeof window.vanishing_global:+ typeof window.vanishing_global +\\\
document.foobar:+ document.foobar);



说明:



把这两个文件进入目录,并在浏览器中打开HTML(在最新的Chrome和Firefox中进行测试,同样的结果)。



这是我得到的输出:



  this == document:false 
this == doc:true
_doc == document:true
_doc == doc:false

名称:foobar
window.vanishing_global:1366037771608
typeof window.vanishing_global:number
document.foobar:barfoo:0.9013048021588475

名称:
window.vanishing_global:undefined
typeof window.vanishing_global:undefined
document.foobar:foobar:0.5015988759696484
/ pre>

处理程序内的这个对象应该是文档对象。它是一个文档对象,但不是与它在里面运行的文档相同的文档对象(它也和父文档不一样)。处理程序中的窗口对象也不同于在页面中加载的JavaScript中运行的窗口对象。



最后我的问题:

$ b有没有人知道发生了什么,以及如何获得对实际窗口对象的引用,或者至少从同一个全局上下文声明和引用全局变量?



脚注:



由于它们位于同一个域,因此此iframe不存在跨域问题。如果有人设置 document.domain ,但是在这个示例代码中没有完成,则会出现问题。

解决方案

您正在声明父页面中的所有内容。因此,引用窗口文档是父页面。如果要对 iframe 执行任务,请使用 iframe.contentWindow || iframe 访问其窗口 iframe.contentDocument || iframe.contentWindow.document 访问其文档



有一个字是什么发生,可能是词汇范围:什么是词汇范围?



范围的唯一上下文是这个。在你的例子中,方法的所有者是 doc ,这是 iframe 文档。除此之外,在该函数中使用已知对象访问的任何内容都是父级(如果未在函数中声明)。如果函数在不同的地方被声明,那么它将是一个不同的故事,但是它在父页面中声明。



这是我如何写:

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

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

其中= 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 作为 w d 不是必需的,它可能会它因为对范围的误解而变得混乱。这样,它们是参数,您必须引用它们才能访问 iframe 的内容。如果您想要访问父母,则仍然使用窗口文档



我不知道在文档中添加方法的含义是什么? doc 这种情况),但在 win 上设置 _l 方法可能更有意义。这样就可以运行没有前缀的东西,例如< body onload =_ l();>< / body>


Before I paste any code, here's the scenario:

  1. I have an HTML document that creates an empty iframe using JavaScript
  2. The JavaScript creates a function and attaches a reference to that function to the iframe's document object (using doc.open() to get a reference to the document)
  3. The function is then attached as an onload handler for the iframe's document (by writing <body onload="..."> into the iframe.

Now what has me stumped is that the global (window) and document objects inside the onload handler (while it's running) is different from the same objects run through JavaScript added via script nodes.

Here's the 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>

And here's 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);

Instructions:

Put these two files into a directory, and open the HTML in a browser (tested in latest Chrome and Firefox, same result in both).

This is the output I get:

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

The this object inside the handler should be either the document object. It is a document object, but not the same document object as the document that it runs inside (it's also not the same as the parent document). The window object inside the handler is also not the same as the window object that runs in JavaScript loaded in the page.

So finally my question:

Does anyone know what's going on, and how I can either get a reference to the actual window object, or at least declare and reference global variable from the same global context?

Footnotes:

There are no cross-domain issues with this iframe since they're on the same domain. There is an issue if someone sets document.domain, but that's not being done in this example code.

解决方案

You're declaring everything in the parent page. So the references to window and document are to the parent page's. If you want to do stuff to the iframe's, use iframe.contentWindow || iframe to access its window, and iframe.contentDocument || iframe.contentWindow.document to access its document.

There's a word for what's happening, possibly "lexical scope": What is lexical scope?

The only context of a scope is this. And in your example, the owner of the method is doc, which is the iframe's document. Other than that, anything that's accessed in this function that uses known objects are the parent's (if not declared in the function). It would be a different story if the function were declared in a different place, but it's declared in the parent page.

This is how I would write it:

(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();
})();

The aliasing of win and doc as w and d aren't necessary, it just might make it less confusing because of the misunderstanding of scopes. This way, they are parameters and you have to reference them to access the iframe's stuff. If you want to access the parent's, you still use window and document.

I'm not sure what the implications are of adding methods to a document (doc in this case), but it might make more sense to set the _l method on win. That way, things can be run without a prefix...such as <body onload="_l();"></body>

这篇关于如何获取对iframe的窗口对象的引用iframe的onload处理程序从父窗口创建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆