2012-02-06 54 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

相關問題