2012-11-09 41 views
0

Possible Duplicate:
jquery passing $(this) to other functions

我寫一個Javascript/jQuery函數(尚未重構),但我使用$(this)得到一個錯誤內。這是一個有點難以解釋,所以我會添加代碼,並希望它會變得更加清晰:

var accordion = 'div.accordionContent'; 
var accordButton = 'div.accordionButton'; 
var accordClosedArrow = 'url(/public/img/accordion-closed-arrow-'; 
var accordOpenArrow = 'url(/public/img/accordion-open-arrow-'; 
$(accordion).hide(); 
var accordFunc = function(arrowColor){ 
    var img; 
    if ($(this).next(accordion).is(':visible')) { 
     img = accordClosedArrow + arrowColor + '.png)'; 
    } 
    else { 
     img = accordOpenArrow + arrowColor + '.png)'; 
    } 

    // these lines throw errors because of $(this) 
    $(this).css({backgroundImage:img}).next().slideToggle('slow').siblings(accordion) 
     .slideUp(); 
    $(this).siblings() 
     .css({backgroundImage:accordClosedArrow + arrowColor + '.png)' + 'no-repeat'}); 
    }; 

    $(accordButton).live('click',function(){ 
     accordFunc('blue'); 
    }); 

    $(accordButton + 'B').live('click',function(){ 
     accordFunc('orange'); 
    }); 

不知道爲什麼經過$(this)導致Chrome瀏覽器控制檯拋出一個錯誤:

Uncaught TypeError: Cannot read property 'firstChild' of undefined

+0

親愛的主,把'$(this)'包裝一次並重用它。 – jbabey

回答

5

更換accordFunc('blue');accordFunc.call(this, 'blue');,同樣做另一個調用該函數。

當您調用accordFunc內部的其他函數時,this值不會保留,它指向窗口對象或null(如果嚴格模式處於活動狀態)。另一種選擇是將this作爲正常參數並改變函數定義,例如到function accordFunc(elem, arrowColor)並使用elem而不是this

+0

完美,謝謝,我是一個JS noob。爲什麼我需要.call? –

+0

看看它的文檔 - 它調用一個函數,它的「this」綁定到第一個參數。 – ThiefMaster

1

當您在JS中的方法中調用函數時,this的範圍將變回窗口。這是一種奇怪的行爲,但不幸的是它的工作方式是這樣的!嘗試通過您所需要的情況下,通過作爲參數傳遞給方法,像這樣:

 var accordFunc = function(ctx, arrowColor){ 
      var img; 
      if ($(ctx).next(accordion).is(':visible')) { 
        img = accordClosedArrow + arrowColor + '.png)'; 
      } 
      else { 
       img = accordOpenArrow + arrowColor + '.png)'; 
      } 

      // these lines throw errors because of $(this)  
      $(ctx).css({backgroundImage:img}).next().slideToggle('slow').siblings(accordion).slideUp(); 
      $(ctx).siblings().css({backgroundImage:accordClosedArrow + arrowColor + '.png)'  + 'no-repeat'}); 
     }; 

     $(accordButton).live('click',function(){ 
      accordFunc(this, 'blue'); 
     }); 
0

一種選擇是讓accordFunc返回將被綁定的功能,並使用封閉的顏色:

var accordFunc = function(arrowColor){ 
    return function(){ 
     var img; 
     if ($(this).next(accordion).is(':visible')) { 
      img = accordClosedArrow + arrowColor + '.png)'; 
     } 
     else { 
      img = accordOpenArrow + arrowColor + '.png)'; 
     } 

     // these lines throw errors because of $(this) 
     $(this).css({backgroundImage:img}).next().slideToggle('slow').siblings(accordion) 
     .slideUp(); 
     $(this).siblings() 
      .css({backgroundImage:accordClosedArrow + arrowColor + '.png)' + 'no-repeat'}); 
    } 
}; 

然後打電話:

$(accordButton + 'B').live('click', accordFunc('orange')); 
相關問題