Анонимная функция событий JavaScript в Firefox

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

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
1 947
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

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

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

Хороший ответ, но ссылка на хорошее объяснение закрытий очень поможет. Я понимаю ваш код, но меня это все равно пугает;) Тот, кто не знает, что такое закрытие, не получит шансов. К сожалению, я нигде в сети не видел четкого и лаконичного объяснения закрытий :(

Gareth 17.11.2008 17:49

К сожалению, мне нужно назначить событие onclick, и из-за этого я не могу передать параметр анонимной функции.

Guillermo Phillips 17.11.2008 19:02

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

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.

Guillermo Phillips 17.11.2008 19:03

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

ng.mangine 17.11.2008 19:41

Спасибо, я пробовал ваш пример, как указано, но он не работает. Это связано с тем, что result.years [result_year_index] .rul_code не входит в область видимости, когда функция вызывается из onClick. На самом деле мне нужно значение переменной (в данном случае 13208), которое нужно передать функции.

Guillermo Phillips 17.11.2008 20:04

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

Вот хорошее объяснение Джона Ресига: Как работают замыкания (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);
}

Вы, конечно, совершенно правы. Никогда не разбивай орех кувалдой, а?

Guillermo Phillips 18.11.2008 12:41

Спасибо за это. Я выдергивал волосы, пытаясь придумать ответ!

Matt Ellen 19.11.2009 20:15

Другие вопросы по теме