【问题标题】:Problems using window.opener使用 window.opener 的问题
【发布时间】:2013-11-25 00:26:13
【问题描述】:

我有一个简单的 ajax 应用程序

从此,弹出一个带有表单的弹出窗口。

表单结果页和 ajax 应用程序都有一个共同的 javascript 文件。

在弹出窗口中,在表单结果页面中,我试图从通用 javascript 文件中调用一个方法,以应用于父窗口。

我的 javascript 文件包含一个 updateLayer 方法,当从父窗口调用时,它工作正常。尝试从弹出窗口调用它时,我什么也得不到。

弹窗中的结果页有

<script type="text/javascript" src="x.js">window.opener.updateLayer("Layer3", "380118179930"); </script>

在任何 html 之前。

父窗口中什么也没有发生。我也试过 window.parent。

这是什么原因和解决方案?

【问题讨论】:

  • David Dorwards 的回答肯定至少是解决方案的一部分——您不能将 src 和 innertext 与脚本混合使用。
  • 没错。不要混在一起。最好在此处的标头中包含 x.js。

标签: javascript html ajax


【解决方案1】:

我假设这与 this question 有关,这是另一个恰好也叫 Josh 的用户提出的问题。

在我对该问题的回答中,我试图解释包含在您的父窗口中的 Javascript 文件中的函数将附加到窗口对象,因此您使用 window.opener 来访问该窗口对象以调用它们.

看起来您几乎已经解决了这个问题,但这里的问题是,通过在表单响应的脚本标记中包含src="x.js",您实际上会覆盖脚本中放置的任何代码。另外,由于 x.js 包含在父窗口中,因此根本不需要在弹出窗口中包含它。

您的表单响应代码应如下所示:

<script type="text/javascript">
window.opener.updateLayer("Layer3", "380118179930");
</script>

我删除了src="x.js" 属性,否则会阻止&lt;script&gt;&lt;/script&gt; 标记之间的代码被执行。

【讨论】:

  • 非常感谢您的帮助。
【解决方案2】:

您的问题可能是您有两个内容相同的 JavaScript 文件,而没有应用命名空间。

首先,您的父级包含定义 updateLayer() 的 file.js。然后父级打开子窗口,其中也包含该 file.js。如果你这样做,你就会有两个线程在运行,每个线程可能都有自己的函数和对象,而不会打扰另一个。我假设您的功能是全球性的。如果没有使用命名空间,这可能会导致问题。您的大型 ajax 库也可能会创建 iframe 和类似的东西,而您不会从中看到任何东西,因为它发生在幕后。

所以试试:top.window.opener.updateLayer("Layer3", "380118179930");

如果这没有帮助,请尝试打开一个没有包含 file.js 的空白窗口,然后从开启程序调用该函数。如果可行,请将 file.js 的内容包装在 myNamespace = {....big file content inbetween....} 之类的命名空间中,制作两个版本(或者更好地动态包含内容)并确保有两个不同的命名空间。 JavaScript 通常无法按照您认为的方式运行。

另外,请确保您打开的窗口的 url 完全具有相同的域。它可能会导致安全问题,从而使浏览器不允许从子窗口访问其父窗口。

【讨论】:

    【解决方案3】:

    乔希,

    您能否确定该功能是否完全被触发,就像 anakata 建议的那样?例如。通过在函数的第一行放置一个警告框?

    否则:函数updateLayerx.js中是如何定义的?

    如果是这样定义的:

    function updateLayer(layer, result) {
      // ...
    }
    

    ...那么它应该可以正常工作。

    如果定义如下:

    var updateLayer = function(layer, result) {
      // ...
    }
    

    那么它将可用作window 对象的属性(因此也不能用作window.opener 的属性)。至少在 Firefox 中;我没有在 IE 或其他浏览器中测试过。

    编辑:为什么这个问题被标记为“ajax”? AFAICS,所有问题都存在于应用程序的客户端;不涉及 ajax。

    【讨论】:

    • 嗨,是的,我按照 Tobias 的建议进行了尝试,效果很好。我同时使用了 x.js 和 window.parent 导致它失败。
    【解决方案4】:

    尝试以下操作:

    parent.window.updateLayer();
    

    在单独的&lt;script&gt; 标记中。

    我不太确定它是否同时适用于 src=some.js 和内联脚本。

    【讨论】:

      【解决方案5】:

      由于你给script元素赋予了src属性,x.js的结果会被解析为JS,元素的文本内容会被忽略。

      <script type="text/javascript" src="x.js"></script>
      <script type="text/javascript">
          window.opener.updateLayer("Layer3", "380118179930");
      </script>
      

      【讨论】:

      • 我正在更新你评论的答案。
      • 应该是 - 假设使用正确的参数调用 updateLayer 函数并且在开启窗口中正确定义。
      • 嗯,还是没有运气。您是不是在上面说 updateLayer 必须在 x.js 之外、在 ajax 应用程序以及弹出窗口中声明?如果是这样的话,那是不可能的,因为它依赖于太多的其他功能......
      • 没有。 updateLayer 只需要是一个可以从加载到打开器窗口的文档中运行的函数(AFAIK 也是首先打开窗口的页面(没有链接)。
      • +1 如果不是 问题,这绝对会是a 问题。 @Josh:您需要证明该方法正在被调用(只需在它的顶部放置一个警报以供初学者使用),如果不是,那么您需要证明该方法是可访问的 "alert(typeof(window.opener. updateLayer))" 并继续向后工作,随时为我们提供更多信息。 Firebug 将极大地帮助您。
      【解决方案6】:

      在你的父 html 文件中创建一个新的 updateLayer 函数。将其重命名为不同的名称并从中调用原始的 updateLayer。 例如

      function updateLayerPage(arg1, arg2)
      {
          updateLayer(arg1, arg2);
      }
      

      然后从子页面调用这个新函数

      window.opener.updateLayerPage("Layer3", "380118179930");
      

      【讨论】:

      • 有没有办法避免这种情况?该功能依赖于其他几个功能......
      • 我看不出有什么理由这样做。如果您可以访问 updateLayerPage,则您可以访问 updateLayer,间接添加什么。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-04
      • 2017-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多