2012-04-16 184 views
1

我正在測試拉斐爾JavaScript庫,我會遇到一個小問題。我在畫布上繪製四種形狀。然後,我可以通過單擊來讓對象成爲當前選定的對象。然後我添加一個監聽刪除鍵的事件處理程序。這工作正常,但我似乎無法調用一個函數。以下是說明我的問題的代碼。無法調用JavaScript函數?

這是表示各在畫布上的圈子的一類:

var Shape = new Class({ 
    initialize: function(x, y, color) 
    { 
     this.shape = paper.circle(x, y, 25); 
     this.shape.attr("fill", color); 

     this.shape.click(function() 
     { 
      if(selectedObj == null) 
      { 
       selectedObj = this; 
       selectedObj.attr({'stroke':'orange', 'stroke-width':'5'}); 
      } 
      else if(selectedObj != this) 
      { 
       selectedObj.attr({'stroke':'orange', 'stroke-width':'0'}); 
       selectedObj = this; 
       selectedObj.attr({'stroke':'orange', 'stroke-width':'5'}); 
      } 
      else if(selectedObj == this) 
      { 
       selectedObj.attr({'stroke':'orange', 'stroke-width':'0'}); 
       selectedObj = null; 
      } 
     }); 
    }, 
    deleteThis: function() 
    { 
     alert("Inside The deleteThis() Function."); 
    } 
}); 

這就產生了一個形狀,並且點擊它執行以下操作時:

  1. 如果selectedObj爲空,被點擊的形狀被設置爲selectedObj,並在形狀周圍繪製一個小型的橙色邊框。
  2. 如果selectedObj不是被單擊的形狀,它將採用先前選定對象的小邊框,然後將新單擊的形狀設置爲當前選定的項目。
  3. 如果形狀是選定的對象,再次單擊時會取消選擇它。

我然後推四種形狀到畫布:

objShapes.push(new Shape(50, 50, "red")); 
objShapes.push(new Shape(250, 50, "blue")); 
objShapes.push(new Shape(50, 250, "yellow")); 
objShapes.push(new Shape(250, 250, "green")); 

現在,我可以選擇併成功取消選擇畫布上的對象,我需要能夠調用所選擇的對象的功能。要觸發我正在使用鍵盤的功能。以下代碼是我使用的:

$(document).keydown(function(event) 
{ 
    if(event.keyCode == 46) 
    { 
     if(selectedObj == null) 
     { 
      alert("nothing to delete"); 
     } 
     else 
     { 
      alert("Deleting " + selectedObj.attr('fill') + " Circle."); 
      selectedObj.deleteThis(); 
     } 
    } 
}); 

只有部分事件處理程序工作。當我點擊刪除鍵並沒有選擇任何東西時,警告窗口告訴我什麼都沒有被選擇刪除,但是,當我選擇了一個對象並點擊刪除鍵時,警告會出現,並告訴我我刪除了哪個圈子但是然後它不能調用deleteThis()函數。我不明白爲什麼它會調用.attr()函數,而不是deleteThis()函數。

不能調用該函數的原因是什麼?

+0

是selectedObj一個jQuery對象?如果不是,那麼爲Shape類定義了attr()? – rlemon 2012-04-16 23:28:58

+1

你在哪裏定義selectedObj?聽起來像一個範圍問題。 – Seabass 2012-04-16 23:31:33

+0

@rlemon,Raphael庫定義了'attr'。 – 2012-04-16 23:33:51

回答

1

問題是selectedObj引用內部shape變量,而不是你的類的對象。您可以使其引用對象本身(請參見下面的代碼;基本上將對象緩存在一個變量中,通常稱爲selfthat,然後在封閉內部將它用作要存儲的對象)。然後參考形狀做selectedObj.shape而不是selectedObj。混淆的原因是您的課程名爲Shape您有一個名爲shape的成員變量。也許考慮改變這些名稱中的一個來避免混淆。

此外,您應該使用調試器與JavaScript控制檯。如果你是,你會看到一個錯誤消息,像「deleteThis沒有在對象上定義」,這將幫助你跟蹤這個。

總之,這裏的上述變化的代碼:

var Shape = new Class({ 
    initialize: function(x, y, color) 
    { 
     // To keep track of the object itself 
     var self = this; 

     this.shape = paper.circle(x, y, 25); 
     this.shape.attr("fill", color); 

     this.shape.click(function() 
     { 
      if(selectedObj == null) 
      { 
       selectedObj = self; // Assign the object, not the shape 
       selectedObj.shape.attr({'stroke':'orange', 'stroke-width':'5'}); 
      } 
      else if(selectedObj != self) // Compare the object, not the shape 
      { 
       selectedObj.shape.attr({'stroke':'orange', 'stroke-width':'0'}); 
       selectedObj = this; // Assign the object, not the shape 
       selectedObj.shape.attr({'stroke':'orange', 'stroke-width':'5'}); 
      } 
      else if(selectedObj == self) // Compare the object, not the shape 
      { 
       selectedObj.shape.attr({'stroke':'orange', 'stroke-width':'0'}); 
       selectedObj = null; 
      } 
     }); 
    }, 
    deleteThis: function() 
    { 
     alert("Inside The deleteThis() Function."); 
    } 
}); 

然後使另一部分相同的調整:

$(document).keydown(function(event) 
{ 
    if(event.keyCode == 46) 
    { 
     if(selectedObj == null) 
     { 
      alert("nothing to delete"); 
     } 
     else 
     { 
      alert("Deleting " + selectedObj.shape.attr('fill') + " Circle."); // Reference the shape here 
      selectedObj.deleteThis(); // This is the object now 
     } 
    } 
});