代码之家  ›  专栏  ›  技术社区  ›  Herms

为什么函数.apply()不能跨IE中的文档边界工作?

  •  5
  • Herms  · 技术社区  · 15 年前

    我在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>
    

    在火狐和Chrome中,所有方法都能正常工作。

    在IE(在6、7和8中测试)中,除了applyargs()和remoteApply()方法外,其他所有方法都按预期工作。

    applyargs()在尝试调用apply(test1.html第11行)时给出“jscript object expected”错误。

    remoteApply()在尝试调用apply(test2.html第5行)时给出相同的“jscript object expected”错误。

    问题是,我需要能够使用apply()。我可以通过执行类似于remoteapplycopy()机制的操作来解决这个问题,但我正试图避免这种情况。为什么apply()不能正常工作?

    4 回复  |  直到 15 年前
        1
  •  6
  •   edsoverflow    15 年前

    您需要在另一个窗口中创建数组,因为每个窗口都有自己的数组构造函数。我想这会奏效的。

    将此函数添加到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()函数。

        2
  •  0
  •   Dan Lew    15 年前

    我不知道这为什么有效,但我在玩弄你的代码,偶然发现了一个解决方案…将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>
    

    我会告诉你我是否能再搞清楚(那样很奇怪)。就像我说的,我只是在玩弄密码。

        3
  •  0
  •   noel aye    15 年前

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

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

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

        4
  •  0
  •   user182669    15 年前

    “……” applyargs()在尝试调用apply(test1.html第11行)时给出“jscript object expected”错误。 remoteApply()在尝试调用apply(test2.html第5行)时给出相同的“jscript object expected”错误。 ……”

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

    (提示:使用调试器)

    ——DJ