Почему function.apply () не работает через границы документа в IE? - PullRequest
5 голосов
/ 09 июля 2009

Я вижу странное поведение в 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 () выдает ошибку «Ожидается объект JScript» при попытке вызова apply (test1.html строка 11).

remoteApply () выдает ту же ошибку «Ожидается объект JScript» при попытке вызова apply (test2.html строка 5).

Проблема в том, что мне нужно использовать apply (). Я могу обойти эту проблему, используя что-то вроде механизма remoteApplyCopy (), но я пытаюсь избежать этого. Почему apply () не работает?

Ответы [ 4 ]

6 голосов
/ 24 июля 2009

Вам нужно создать массивы в другом окне, потому что у каждого окна есть свой собственный конструктор 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 (), но я не мог заставить это работать. Если бы вы могли это сделать, вы могли бы избавиться от новой функции getEmptyArray () в test2.html.

0 голосов
/ 28 сентября 2009

"... applyArgs () выдает ошибку" Ожидается объект JScript "при попытке вызова apply (test1.html строка 11). RemoteApply () выдает ту же ошибку" Ожидается объект JScript "при попытке вызова apply (test2.html строка 5). ... "

Какой именно объект не является" объектом JScript ", как" ожидается "?

(подсказка: используйте отладчик)

-DBJ

0 голосов
/ 09 июля 2009

Если вы измените функцию test2.html testApply () следующим образом:

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

remoteApply () работает. Но applyArgs () все равно не удалось.

0 голосов
/ 09 июля 2009

Понятия не имею, почему это работает, но я поигрался с вашим кодом и наткнулся на одно решение ... поместил функции 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 странный, как это). Как я уже сказал, я просто играл с кодом.

...