简体   繁体   中英

jQuery plugin returning “Cannot read property of undefined”

I'm trying to do something i've done numerous times. I can't figure out why this isn't working. No matter how i write the jQuery code, it doesn't work. menuitems[i].action() just does NOT work. Below is Example 1 in which this example, no matter what item is clicked it returns the last item's action (in this example it's the alert('Forward!') ). The 2nd returns undefined property. The full error below.

My jQuery plugin is called like this (examples below are what happen with this same call):

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

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

This returns an alert with Forward! no matter which item, Back or Forward, is clicked.

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

I get:

Uncaught TypeError: Cannot read property 'action' of undefined

Other random things i tried were detaching the click and reattaching it outside of that appendTo() block, changed action() to newtest() to make sure it wasn't conflicting with any built in keywords. I also tried doing a $('body').append('<li>{blah blah}</li>').find('li').click(function(){/*blah blah*/}); but it still returned the same thing. I'm outta ideas!

The problem is that "i" is incremented, so by the time the click event is executed the value of i equals len. One possible solution is to capture the value of i inside a function:

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 the above sample, the anonymous function creates a new scope which captures the current value of i, so that when the click event is triggered the local variable is used instead of the i from the for loop.

I had same problem with 'parallax' plugin. I changed jQuery librery version to *jquery-1.6.4* from *jquery-1.10.2*. And error cleared.

Usually that problem is that in the last iteration you have an empty object or undefine object. use console.log() inside you cicle to check that this doent happend.

Sometimes a prototype in some place add an extra element.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM