2010-11-12 4 views
11

Ich versuche etwas zu tun, was ich schon oft gemacht habe. Ich kann nicht herausfinden, warum das nicht funktioniert. Egal wie ich den jQuery Code schreibe, es funktioniert nicht. menuitems[i].action() funktioniert einfach nicht. Unten ist Beispiel 1 in dem dieses Beispiel, egal welches Element geklickt wird, die Aktion des letzten Elements zurückgibt (in diesem Beispiel ist es die alert('Forward!')). Die 2. gibt undefined Eigenschaft zurück. Der vollständige Fehler unten.jQuery plugin returning "Kann Eigenschaft von undefined nicht lesen"

Meine jQuery-Plugin wird wie folgt aufgerufen (Beispiele unten sind, was mit diesem gleichen Anruf passieren):

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

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

Dies gibt eine Warnung mit Forward! egal auf welchen Gegenstand, Zurück oder Vorwärts, geklickt wird.

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

ich:

Uncaught TypeError: Cannot read property 'action' of undefined

andere zufällige Dinge, die ich versuchte, wurden die Klick abgenommen und es außerhalb dieses appendTo() Block wieder anbringen, geändert action() zu newtest() zu machen sicher, dass es keinen Konflikt mit irgendwelchen eingebauten Keywords gab. Ich habe auch versucht, eine $('body').append('<li>{blah blah}</li>').find('li').click(function(){/*blah blah*/});, aber es immer noch die gleiche Sache. Ich habe keine Ideen!

+0

Haben Sie versucht, dies mit einem Debugger zu durchlaufen? – Phil

+0

Haben Sie Empfehlungen zu einem Debugger? Ich verwende nur Chrome Inspektor –

+0

Versuchen Sie, firebox, ein Firefox-Addon – subosito

Antwort

16

Das Problem ist, dass "i" inkrementiert wird. Wenn also das click-Ereignis ausgeführt wird, ist der Wert von i gleich len. Eine mögliche Lösung ist es, den Wert von i in einer Funktion zu erfassen:

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

In dem obigen Beispiel wird die anonyme Funktion erstellt einen neuen Rahmen, der den aktuellen Wert von i erfasst, so dass, wenn das Click-Ereignis ausgelöst wird, Die lokale Variable wird anstelle des i aus der for-Schleife verwendet.

+0

Genius! Duh, ich kann nicht glauben, dass ich nicht darüber nachgedacht habe ... Danke, das wird funktionieren. Vielen Dank –

0

Normalerweise ist das Problem, dass Sie in der letzten Iteration ein leeres Objekt oder ein undefiniertes Objekt haben. Verwenden Sie console.log() in Ihrem cicle, um zu überprüfen, ob dieser Vorgang stattgefunden hat.

Manchmal fügt ein Prototyp an einer Stelle ein zusätzliches Element hinzu.

0

Ich hatte das gleiche Problem mit "Parallax" -Plugin. Ich änderte jQuery Librery Version zu *jquery-1.6.4* von Und Fehler behoben.

Verwandte Themen