是什么导致的'未捕获的类型错误:无法调用方法'animate'未定义的'错误

What is causing this 'Uncaught TypeError: Cannot call method 'animate' of undefined' error?

本文关键字:错误 调用 方法 animate 未定义 是什么 类型      更新时间:2023-09-26

全部,

请参阅以下代码:

function menu() {
    this.menuitem=[];
    this.submenu=[];
    this.menuitem[0] = $('div#sivname1');
    this.menuitem[1] = $('div#divname2');
    this.submenu[0] = $('div#submenu1');
    this.submenu[1] = $('div#submenu2');
    this.active = false;
    this.timeout;
}
menu.prototype = {
    animatedown: function(submenu) {
        submenu.animate({top: '99px'}, 200);
    },
    animateup: function(submenu) {
        submenu.animate({top: '-4px'}, 200);
    }
}
var menu = new menu();
z=2;
while(z--) {
    console.log(z);
    menu.menuitem[z].hover(
    function() { //mouseover
        if(menu.active) {
            clearTimeout(menu.submenu[z].data("timeout"));
        }
        else {
            menu.animatedown(menu.submenu[z])
        };
    },
    function() { //mouseleave
        $(this).data("timeout", setTimeout(function({
            menu.animateup(menu.submenu[z])
        },200));
        menu.active = false;    
    }),
    menu.submenu[z].hover(
    function() { //mouseover
        menu.active = true;
        if (menu.menuitem[z].data("timeout")) {
            clearTimeout(menu.menuitem[z].data("timeout"));
        };
    }, 
    function() { //mouseleave
        $(this).data("timeout", setTimeout(function() {
            menu.animateup(menu.submenu[z]);menu.active = false;
        },200));   
    });
}

此代码给出以下错误:

未捕获的类型错误:无法调用未定义的方法"animate"

奇怪的是,我补充道:

z=0; 

在代码的底部,它将正常工作。我希望它在没有z=0的情况下工作,当我添加它时,我不知道为什么会这样。谁能解释一下吗?

问题出在闭包中,以下代码有效:

z=1;
while(z--){
  (function(z) {
    console.log(z);
      menu.menuitem[z].hover(
        function(){ //mouseover
          if(menu.active){clearTimeout(menu.submenu[z].data("timeout"));}
          else{menu.animatedown(menu.submenu[z])};
        }, 
        function(){ //mouseleave
          $(this).data("timeout", setTimeout(function(){menu.animateup(menu.submenu[z])},200));
          menu.active = false;    
        }
      )
      menu.submenu[z].hover(
        function(){ //mouseover
          menu.active = true;
          if(menu.menuitem[z].data("timeout")){clearTimeout(menu.menuitem[z].data("timeout"));};
        }, 
        function(){ //mouseleave
          $(this).data("timeout", setTimeout(function(){menu.animateup(menu.submenu[z]);menu.active = false;},200));   
        }
      );
  })(z); //this is to enable closures http://bonsaiden.github.com/JavaScript-Garden/#function.closures
}

首先,您在代码中有一个错误:

$(this).data("timeout", setTimeout(function({
    menu.animateup(menu.submenu[z])
},200));

应为:

$(this).data("timeout", setTimeout(function() {
    menu.animateup(menu.submenu[z]);
},200);

第二:z是全局的,您的回调将使用初始化后的最后一个值。您应该为回调创建z的本地副本,并在循环中使用闭包,如下所示:

while (z--) {
    (function(z) {
        /* your code */
    })(z);
}

通过这种方式,您可以将while循环的z的值以及其中的回调包含在内

z=0奇怪之处是,当循环终止时(由于z为0),递减运算符将再运行一次,z将为-1。-1索引将用于所有回调,为没有animate of c的非对象建立索引。但是(!)如果您将其设置为z=0,那么它将对对象进行索引,但始终是索引为0的对象。您必须使用上面的更正才能在每个菜单项中获得良好的结果。

这是因为您的submenu项很可能是而不是jQuery对象。

您有nosubmenu[2],这是z变量的起始位置。

你可能想把它切换到:

while(--z) ...

它应该在1开始您的z