web-dev-qa-db-fra.com

le plugin jQuery renvoyé "Impossible de lire la propriété d'un défini"

J'essaie de faire quelque chose que j'ai fait de nombreuses fois. Je n'arrive pas à comprendre pourquoi ça ne marche pas. Peu importe comment j'écris le code jQuery, cela ne fonctionne pas. menuitems[i].action() ne fonctionne tout simplement pas. Vous trouverez ci-dessous Exemple 1 dans lequel cet exemple, quel que soit l'élément sur lequel vous cliquez, renvoie l'action du dernier élément (dans cet exemple, il s'agit du _alert('Forward!')). Le 2nd retourne une propriété non définie. L'erreur complète ci-dessous.

Mon plugin jQuery s’appelle comme ceci (les exemples ci-dessous montrent 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 avec Forward! peu importe quel élément, en arrière ou en avant, 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: Impossible de lire propriété 'action' de non définie

D'autres choses aléatoires que j'ai essayées consistaient à détacher le clic et à le rattacher en dehors de ce bloc appendTo(), a remplacé action() en newtest() afin de s'assurer qu'il n'était pas en conflit avec des 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 retournait toujours la même chose. Je suis hors d'idées!

11
Oscar Godson

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 égal à len . Une solution possible consiste à 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. Ainsi, lorsque l'événement click est déclenché, la variable locale est utilisée à la place de i dans la boucle for.

16
nxt

Généralement, ce problème vient du fait que lors de la dernière itération, vous avez un objet vide ou un objet non défini. utilisez console.log () dans votre cicle pour vérifier que cela s’est bien passé.

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

0
Siedrix

J'ai eu le même problème avec le plugin 'parallax' . J'ai changé la version de la bibliothèque jQuery en *jquery-1.6.4* à partir de *jquery-1.10.2*.

0
byJeevan