2012-04-16 124 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 
     } 
    } 
});