2010-11-12 41 views
11

J'essaie de faire quelque chose que j'ai fait de nombreuses fois. Je n'arrive pas à comprendre pourquoi cela ne fonctionne pas. Peu importe comment j'écris le code jQuery, ça ne marche pas. menuitems[i].action() ne fonctionne tout simplement pas. Ci-dessous est Exemple 1 dans lequel cet exemple, quel que soit l'élément est cliqué, il renvoie l'action du dernier élément (dans cet exemple, il est le alert('Forward!')). La 2ème renvoie une propriété non définie. L'erreur complète ci-dessous.Le plugin jQuery renvoyant "Impossible de lire la propriété de undefined"

Mon plugin jQuery est appelé comme celui-ci (exemples ci-dessous sont ce qui se passe avec ce même appel):

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

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

Cela renvoie une alerte à l'avant! quel que soit l'élément, Back ou Forward, est cliqué.

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

Je reçois:

Uncaught TypeError: Cannot read property 'action' of undefined

Autres choses au hasard i essayé se détacher le clic et reconnectez-dehors de ce bloc appendTo(), changé action() à newtest() pour faire Assurez-vous qu'il n'était pas en conflit avec les mots-clés intégrés. J'ai aussi essayé de faire un $('body').append('<li>{blah blah}</li>').find('li').click(function(){/*blah blah*/}); mais il restait toujours la même chose. Je suis sorti des idées!

+0

Avez-vous essayé de le faire avec un débogueur? – Phil

+0

Avez-vous des recommandations sur un débogueur? Je n'utilise que l'inspecteur de Chrome –

+0

Essayez firebug, un addon firefox – subosito

Répondre

16

Le problème est que "i" est incrémenté, donc au moment où l'événement click est exécuté, la valeur de i est égale à len. Une solution possible est de capturer la valeur de i dans une fonction:

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

Dans l'exemple ci-dessus, la fonction anonyme crée une nouvelle portée qui capture la valeur actuelle de i, de sorte que lorsque l'événement click est déclenché la variable locale est utilisée à la place de l'i de la boucle for.

+0

Genius! Duh, je ne peux pas croire que je n'ai pas pensé à ça ... Merci, ça va marcher. Merci beaucoup –

0

Généralement, ce problème est dû au fait qu'à la dernière itération, vous avez un objet vide ou un objet indéfini. utilisez console.log() à l'intérieur de votre cicle pour vérifier que ce doent est arrivé.

Parfois, un prototype à un endroit ajoute un élément supplémentaire.

0

J'ai eu le même problème avec le plugin 'parallaxe'. J'ai changé la version de librairie jQuery à *jquery-1.6.4* de *jquery-1.10.2*. Et l'erreur a été effacée.