Плагин jQuery возвращает "Невозможно прочитать свойство undefined"

Я пытаюсь сделать что-то, что я делал много раз. Я не могу понять, почему это не работает. Независимо от того, как я пишу код jQuery, он не работает. menuitems[i].action() просто НЕ работает. Ниже Пример 1, в котором этот пример, независимо от того, какой элемент щелкнул, возвращает последнее действие элемента (в этом примере это alert('Forward!')). Второй возвращает свойство undefined. Полная ошибка ниже.

Мой плагин jQuery вызывается вот так (примеры ниже, что происходит с этим же вызовом):

$('p').contextMenu([
    {
        name:'Back',
        action:function(){
            alert('Back!');
        },
        icon:'http://cdn.iconfinder.net/data/icons/crystalproject/16x16/actions/agt_back.png'
    },
    {
        name:'Forward',
        action:function(){
            alert('Forward!');
        },
        icon:'http://cdn.iconfinder.net/data/icons/crystalproject/16x16/actions/agt_forward.png'
    }
]);

Пример 1:

for (i in menuitems){
    $('<li/>',{
        'html':'<img src="'+menuitems[i].icon+'">'+menuitems[i].name,
        'class':o.itemClass,
        'click':function(){
            menuitems[i].action();
        }
    }).appendTo('.'+o.listClass);
}

Это возвращает предупреждение с помощью Forward! независимо от того, какой элемент, Назад или Вперед, щелкнут.

Пример 2:

var len = menuitems.length;
for (var i = 0; i < len; i++){
    $('<li/>',{
        'html':'<img src="'+menuitems[i].icon+'">'+menuitems[i].name,
        'click':function(){
            menuitems[i].action();
        },
        'class':o.itemClass
    }).appendTo('.'+o.listClass);
}

Я получаю:

Неподготовлено TypeError: невозможно прочитать свойство "действие" undefined

Другие случайные вещи, которые я пытался, отделили щелчок и снова подключили его за пределами этого блока appendTo(), изменили action() на newtest(), чтобы убедиться, что он не противоречит каким-либо встроенным ключевым словам. Я также попытался сделать $('body').append('<li>{blah blah}</li>').find('li').click(function(){/*blah blah*/});, но он все равно вернул то же самое. У меня есть идеи!

Ответ 1

Проблема заключается в том, что "i" увеличивается, поэтому к моменту выполнения события click значение я равно len. Одним из возможных решений является захват значения я внутри функции:

var len = menuitems.length;
for (var i = 0; i < len; i++){
    (function(i) {
      $('<li/>',{
          'html':'<img src="'+menuitems[i].icon+'">'+menuitems[i].name,
          'click':function(){
              menuitems[i].action();
          },
          'class':o.itemClass
      }).appendTo('.'+o.listClass);
    })(i);
}

В приведенном выше примере анонимная функция создает новую область, которая фиксирует текущее значение i, так что, когда срабатывает событие click, вместо я из цикла for используется локальная переменная.

Ответ 2

Обычно эта проблема заключается в том, что в последней итерации у вас есть пустой объект или объект undefine. используйте console.log() внутри вас, чтобы проверить, что этот вопрос появился.

Иногда прототип в некотором месте добавляет дополнительный элемент.

Ответ 3

У меня была такая же проблема с плагином "parallax". Я изменил версию lQuery librery до *jquery-1.6.4* от *jquery-1.10.2*. И ошибка очищена.