Я пытаюсь зарегистрировать анонимную функцию, когда пользователь щелкает ячейку в таблице 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.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы пробовали что-то подобное?
document.getElementById('course' + displayed_year_index + occurences_indices[displayed_year_index]) =
function (nr)
{
return function () { PrintReceipt(nr) }
} (result.years[result_year_index].rul_code);
Не могли бы вы опубликовать цикл, чтобы помочь нам найти проблему, вместо того, чтобы заставлять нас угадывать, что вы пытаетесь сделать?
К сожалению, мне нужно назначить событие onclick, и из-за этого я не могу передать параметр анонимной функции.
Похоже, вы хотели бы пойти именно в этом направлении:
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 будет создано в другой области (каждая итерация цикла). Об остальном позаботится Закрытие.
Это не работает, потому что параметр PrintReceipt должен быть константой при вызове onclick.
Он не должен быть константой, потому что функция будет вызываться в исходной области видимости при возникновении события.
Спасибо, я пробовал ваш пример, как указано, но он не работает. Это связано с тем, что result.years [result_year_index] .rul_code не входит в область видимости, когда функция вызывается из onClick. На самом деле мне нужно значение переменной (в данном случае 13208), которое нужно передать функции.
Используйте закрытие, как предложил Том.
Вот хорошее объяснение Джона Ресига: Как работают замыкания (pdf)
В этом случае не следует использовать закрытие 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);
}
Вы, конечно, совершенно правы. Никогда не разбивай орех кувалдой, а?
Спасибо за это. Я выдергивал волосы, пытаясь придумать ответ!
Хороший ответ, но ссылка на хорошее объяснение закрытий очень поможет. Я понимаю ваш код, но меня это все равно пугает;) Тот, кто не знает, что такое закрытие, не получит шансов. К сожалению, я нигде в сети не видел четкого и лаконичного объяснения закрытий :(