如何从父窗口创建的iframe的onload处理程序内的iframe的window对象的引用(How

2019-08-31 06:46发布

之前我粘贴任何代码,这里的情景:

  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 ,但不是被在这个示例代码来完成。

Answer 1:

你在声明父页面的一切。 因此,要引用windowdocument是父页面的。 如果你想要做的东西到iframe的,使用iframe || iframe.contentWindow iframe || iframe.contentWindow访问其window ,并iframe.contentDocument || iframe.contentWindow.document iframe.contentDocument || iframe.contentWindow.document访问其document

有对所发生的事情,可能是“词法范围”的一句话: 什么是词法范围?

一个范围的只有背景是这样的。 而在你的榜样,该方法的所有者是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();
})();

的混叠windocwd是没有必要的,它只是可能使因为范围的误解不那么混乱。 这样一来,他们的参数,你必须引用它们访问iframe的东西。 如果您要访问的父母的,你仍然可以使用windowdocument

我不知道是什么含义是添加方法到的documentdoc在这种情况下),但它可能会更有意义设置_l的方法win 。 这样一来,事情可以没有前缀运行...如<body onload="_l();"></body>



文章来源: How to get a reference to an iframe's window object inside iframe's onload handler created from parent window