繁体   English   中英

为什么function.apply()无法跨IE中的文档边界工作?

[英]Why doesn't function.apply() work across document boundaries in IE?

我在IE中看到一些奇怪的行为,试图通过function.apply()调用另一个页面中的函数。

这是一个简单的测试用例:

test1.html:

<HTML>
<HEAD>
<script language="javascript" type="text/javascript">
  var opened = null;

  function applyNone() {
    opened.testFunc.apply(opened);
  }

  function applyArgs() {
    opened.testFunc.apply(opened, ["applied array"]);
  }

  function call() {
    opened.testFunc("called directly");
  }

  function remoteApply() {
    opened.testApply(["used remote apply"]);
  }

  function remoteApplyCopy() {
    opened.testApplyCopy(["used remote apply copy"]);
  }

  function openPopup() {
    opened = window.open("test2.html", "_blank");
  }
</script>
</HEAD>
<BODY>
  <a href="#" onclick="openPopup()">OPEN</a>
  <hr>
  <a href="#" onclick="applyNone()">applyNone</a>
  <a href="#" onclick="applyArgs()">applyArgs</a>
  <a href="#" onclick="call()">call</a>
  <a href="#" onclick="remoteApply()">remoteApply</a>
  <a href="#" onclick="remoteApplyCopy()">remoteApplyCopy</a>
</BODY>
</HTML>

test2.html:

<HTML>
<HEAD>
<script language="javascript" type="text/javascript">
  function testApply(args) {
    testFunc.apply(this, args);
  }

  function testApplyCopy(args) {
    var a = [];
    for(var i = 0; i < args.length; i++) {
      a.push(args[i]);
    }
    testFunc.apply(this, a);
  }

  function testFunc() {
    var s = "Got: ";
    for(var i = 0; i < arguments.length; i++) {
      s += arguments[i] + " ";
    }
    document.getElementById("output").innerHTML += s + "<BR>";
  }
</script>
</HEAD>
<BODY>
  Hi there
  <div id="output"/>
</BODY>
</HTML>

在firefox和chrome中,所有方法均可正常使用。

在IE中(在6、7和8中进行了测试),applyArgs()和remoteApply()方法以外的所有方法均按预期工作。

applyArgs()尝试调用apply时会出现“预期的JScript对象”错误(test1.html第11行)。

当remoteApply()尝试调用apply(test2.html第5行)时,会给出相同的“预期的JScript对象”错误。

问题是,我需要能够使用apply()。 我可以通过执行remoteApplyCopy()机制来解决此问题,但我正努力避免这种情况。 为什么apply()不起作用?

您需要在另一个窗口中创建数组,因为每个窗口都有自己的Array构造函数。 我认为这会起作用。

将此函数添加到test2.html:

function getEmptyArray() {
    return new Array();
}

并将此功能改为test1.html:

Array.prototype.cloneToRemote = function (win) {
    var newArray = win.getEmptyArray();
    for (var i = 0; i < this.length; i++)
    {
        newArray.push(this[i]);
    }
    return newArray;
}

然后执行以下操作:

function applyArgs() {
    opened.testFunc.apply(opened, ["applied array"].cloneToRemote(opened));
}

请注意,看来您应该能够做到

var newArray = new win.Array();

在test1.html cloneToRemote()函数中,但是我无法使它工作。 如果可以这样做,则可以摆脱test2.html中新的getEmptyArray()函数。

我不知道为什么这行得通,但是我在玩弄您的代码,偶然发现了一个解决方案……将test2的函数放在test1内,它可以工作:

<HTML>
<HEAD>
<script language="javascript" type="text/javascript">
  var opened = null;

  function applyArgs() {
    testFunc.apply(opened, ["applied array"]);
  }

  function openPopup() {
    opened = window.open("test2.html", "_blank");
  }

  function testFunc() {
    var s = "Got: ";
    for(var i = 0; i < arguments.length; i++) {
      s += arguments[i] + " ";
    }
    this.document.getElementById("output").innerHTML += s + "<BR>";
  }
</script>
</HEAD>
<BODY>
  <a href="#" onclick="openPopup()">OPEN</a>
  <hr>
  <a href="#" onclick="applyArgs()">applyArgs</a>
</BODY>
</HTML>

我会让您知道是否可以解决更多问题(IE很奇怪)。 就像我说的那样,我只是在玩弄代码。

如果您更改test2.html testApply()函数,如下所示:

function testApply() {
    testFunc.apply(this, arguments);
}

remoteApply()有效。 但是,applyArgs()仍然失败。

“ ... applyArgs()尝试调用apply时会出现“预期的JScript对象”错误(test1.html第11行)。remoteApply()尝试调用apply时会出现相同的“预期JScript对象”的错误。 5)。...”

哪个确切对象不是“预期”的“ JScript对象”?

(提示:使用调试器)

--DBJ

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM