Firefox Javascript Events Анонимная функция - PullRequest
1 голос
/ 17 ноября 2008

Я пытаюсь зарегистрировать анонимную функцию, когда пользователь щелкает ячейку в таблице HTML. Вот некоторый необработанный, незапятнанный код:

document.getElementById(
    "course"+displayed_year_index+occurrences_indices[displayed_year_index]).onclick =
        eval("function() {PrintReceipt("+result.years[result_year_index].rul_code+");};");

Обратите внимание на использование eval, так как это находится в цикле, и анонимная функция каждый раз отличается.

Достаточно сказать, что это отлично работает в Firefox 2. Но Firefox 3 выдает «Синтаксическую ошибку», указывающую в скобках после слова «функция».

У кого-нибудь есть какие-нибудь умные идеи о том, как я могу это исправить?


Чтобы прояснить, что я пытаюсь сделать, приведу очень упрощенный пример:

for (index=0; index<4; index++) {
    document.getElementById("div"+index).onclick = 
        eval("function () {Foo(index);};");
}

Другими словами, я хочу вызвать одну и ту же функцию с различным значением параметра для каждого div.

Ответы [ 4 ]

5 голосов
/ 17 ноября 2008

Вы пробовали что-то подобное?

document.getElementById('course' + displayed_year_index + occurences_indices[displayed_year_index]) =
    function (nr)
    {
        return function () { PrintReceipt(nr) }
    } (result.years[result_year_index].rul_code);

Не могли бы вы опубликовать цикл, чтобы помочь нам найти проблему, вместо того, чтобы заставить нас угадать, что вы пытаетесь сделать?

4 голосов
/ 17 ноября 2008

IMHO замыкания не должны использоваться в этом случае, и нет необходимости создавать новую функцию для каждого onlick (использует гораздо больше памяти, чем необходимо), а eval - неправильный ответ.

Вы знаете, что элемент, который вы получаете с getElementById, является объектом и что вы можете присвоить ему значения?

for ( /* your definition */ ) {
  var e = document.getElementById(
    "course"+displayed_year_index+occurrences_indices[displayed_year_index]
  );
  e.rul_code = result.years[result_year_index].rul_code;
  e.onclick = PrintReceipt;
}

Но сначала вы должны определить PrintReceipt:

function PrintReceipt() {
  //This function is called as an onclick handler, and "this" is a reference to the element that was clicked.
  if (this.rul_code === undefined) { return; }
  //Do what you want with this.rul_code
  alert (this.rul_code);
}
1 голос
/ 17 ноября 2008

Используйте замыкания, как предложил Том.

Вот хорошее объяснение Джона Резига: Как работают замыкания (pdf)

0 голосов
/ 17 ноября 2008

Похоже, что это направление, в котором вы хотели бы пойти:

document.getElementById("course"+displayed_year_index+occurrences_indices[displayed_year_index]).addeventlistener("click",  function() {
    var current_rul_code = result.years[result_year_index].rul_code;
    PrintReceipt(current_rul_code);
}, true);

Это должно привести к тому, что каждое событие onclick будет создано в другой области видимости (каждая итерация цикла). Затворы позаботятся об остальном.

...