2010-11-12 14 views
11

Estoy intentando hacer algo que he hecho en numerosas ocasiones. No puedo entender por qué esto no está funcionando. No importa cómo escribo el código jQuery, no funciona. menuitems[i].action() simplemente NO funciona. Debajo está Ejemplo 1 en el cual este ejemplo, sin importar en qué elemento se haga clic, devuelve la acción del último elemento (en este ejemplo es alert('Forward!')). El segundo devuelve propiedad indefinida. El error completo a continuación.Plugin de jQuery que devuelve "No se puede leer la propiedad de indefinido"

Mi plugin de jQuery se llama así (ejemplos a continuación son lo que sucederá con esta misma llamada):

$('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' 
    } 
]); 

Ejemplo 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); 
} 

Esto devuelve una alerta con Adelante! no importa qué elemento, Atrás o Adelante, se haga clic.

Ejemplo 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); 
} 

me sale:

Uncaught TypeError: Cannot read property 'action' of undefined

Otras cosas al azar que probamos estaban separando el clic y volver a colocar fuera de ese appendTo() bloque, cambiado action() a newtest() hacer Seguro que no estaba en conflicto con ninguna palabra clave incorporada. También intenté hacer un $('body').append('<li>{blah blah}</li>').find('li').click(function(){/*blah blah*/}); pero aún así devolví la misma cosa. ¡Estoy fuera de las ideas!

+0

¿Has intentado pasar esto con un depurador? – Phil

+0

¿Alguna recomendación sobre un depurador? Solo estoy usando el inspector de Chrome –

+0

Pruebe Firebug, un complemento de Firefox – subosito

Respuesta

16

El problema es que "i" se incrementa, por lo que cuando se ejecuta el evento de clic, el valor de i es igual a len. Una posible solución consiste en capturar el valor de i dentro de una función:

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); 
} 

En el ejemplo anterior, la función anónima crea un nuevo ámbito que captura el valor actual de i, de manera que cuando se activa el evento click la variable local se usa en lugar de i desde el ciclo for.

+0

Genius! Duh, no puedo creer que no haya pensado en esto ... Gracias, esto funcionará. Gracias un montón –

0

Por lo general, ese problema es que en la última iteración tiene un objeto vacío o indefinido. use console.log() dentro de su ciclo para verificar que esto sucedió.

A veces, un prototipo en algún lugar agrega un elemento adicional.

0

Tuve el mismo problema con el complemento 'parallax'. Cambié la versión de jQuery a *jquery-1.6.4* desde *jquery-1.10.2*. Y se borra el error.

Cuestiones relacionadas