2012-02-06 90 views
0

所有,这是什么导致'未捕获的类型错误:无法调用未定义'错误的方法'动画?

请参见下面的代码:

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

此代码提供了以下错误:

Uncaught TypeError: Cannot call method 'animate' of undefined

而且奇怪这是我补充一下:

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 
} 
+0

什么是'animateup'和'animatedown'? – Neal 2012-02-06 21:22:42

+0

我添加了animateup和animatedown代码。 – 2012-02-06 21:23:15

+2

它看起来像是在多个函数中使用单个变量,但期望每个函数中的变量都不相同。阅读[this](http://bonsaiden.github.com/JavaScript-Garden/#function。关闭)(“闭环内闭合”)。 – pimvdb 2012-02-06 21:25:27

回答

1

首先,你必须在代码中的错误:

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

这样你附上的z为while循环的价值,并在它的回调。

奇怪事情z=0的是,当循环死亡(因为z为0)递减操作将运行一个更多的时间,而z将是-1。 -1索引将用于所有回调中,索引一个非对象,该对象不具有动画。但是(!)如果设置为z=0,那么它将索引一个对象,但始终是索引为0的索引。您必须使用上述更正才能在每个菜单项中获得良好结果。

0

这是因为你的submenu产品最有可能一个jQuery对象。

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

您可能需要将其切换到:

while(--z) ... 

哪些应该启动z为1

+0

'--z' /'ž谈论一个错误 - '只有在它们的返回值,这里没有使用不同。在'while'循环中'z'永远不会是'2'。 – pimvdb 2012-02-06 21:28:03

+0

@pimvdb嗯这是真的...... – Neal 2012-02-06 21:29:08

相关问题