2011-09-28 66 views
2

我有一个16x16的按钮网格,并且希望为每个按钮添加一个事件监听器,因此单击它时将返回其唯一的网格位置编号(0到255之间的任何值); 我有什么至今:动态地将参数传递给事件监听器AS3

public static const GRID_SIZE:Number = 16; 
    private var i:int; 
    private var j:int; 

    // Constructor 
    public function Grid() 
    { 
     for (i = 0; i < GRID_SIZE; i++) 
     { 
      for (j = 0; j < GRID_SIZE; j++) 
      { 
       // Creates new instance of GridButton, a custom class that extends SimpleButton 
       var button:GridButton = new GridButton(); 

       // Arranges buttons into a grid 
       button.x = (i + 1) * button.width; 
       button.y = (j + 1) * button.height; 

       // Create unique value for grid position 
       var position:Number = i * GRID_SIZE + j; 

       // Add listener to button, with position as extra param 
       button.addEventListener(MouseEvent.CLICK, function(e:MouseEvent) : void { buttonClick(e, position) }); 

       // Adds button to Sprite 
       addChild(button); 
      } 
     } 
    } 
} 

不幸的是每一个听者的功能是由每个按钮调用的时候,它使用i和j的最后两个值,它在每一个按钮这种情况下返回255。

有什么建议吗?

+0

您也可以使用闭包。检查我的答案以下问题:http://stackoverflow.com/questions/7396845/how-to-use-a-method-of-a-class-inside-a-callback-function-in-actionscript/7412402# 7412402 –

+0

除非您完全理解使用闭包的后果,否则不应使用它们。 –

回答

1

你可以添加一个名字到该按钮,例如button.name = "button" + position;和事件处理函数,你可以提取目标名称(e.target.name)位置参数:

button.name = "button" + position; 
button.addEventListener(MouseEvent.CLICK, buttonClick); 

和事件处理程序:

function buttonClick(e:MouseEvent) { 
    var position:Number = Number(e.target.name.replace("button", "")); 
    // ... do wathever you want with position parameter 
} 
0

您可以从用于将x和y值分配给按钮的相同表达式中获取i和j的值。例如:

button.addEventListener(MouseEvent.CLICK, clickHandler); 

function clickHandler(e:MouseEvent) { 
    var i:int = (e.target.x/e.target.width) - 1; 
    var j:int = (e.target.y/e.target.height) - 1; 

    var position:Number = i * GRID_SIZE + j; 
} 
1

还有一些其他的选择...

使用signals而不要使用闪光灯事件监听器,here's a post描述它,并给出更多的细节。另外一个video tutorial让你快速入门。我提出这个建议的原因是你可以设置一个信号来传递一个参数,所以你不需要使用事件目标,它并不总是最好的。

使用功能工厂。

// factory: 
public function fooFactory($mc:GridButton):Function{ 
    var $f:Function = new Function($e:MouseEvent):void{ 
     trace($mc.x, $mc.y); 
    } 
    // you might want to consider adding these to a dictionary or array, so can remove the listeners to allow garbage collection 
    return $f; 
} 


// then assign the function to the button like this 
button.addEventListener(MouseEvent.CLICK, fooFactory(button)); 

这样做基本上是你想要做什么,但它会工作,因为position VAR没有改变。在你的代码中,position每次循环执行时都会改变,然后当你启动监听器函数时,它会使用最后一个值position被赋值,这就是为什么你得到了255的全部值。让我知道如果这是没有意义的...

0

我试过这个,它工作得很好....即。点击不同的文本字段追踪不同的值。 的想法是创建一个新的参考POS:号码,这样即使更新POS机后,关闭仍指向旧

package 
{ 
    import flash.display.Sprite; 
    import flash.events.MouseEvent; 
    import flash.text.TextField; 
    import flash.text.TextFieldType; 

    public class AsDing extends Sprite 
    { 
     private static const GRID_SIZE:uint = 2; 
     public function AsDing() 
     { 
      for(var i:uint=0; i<GRID_SIZE; i++) 
      { 
       for(var j:uint=0; j<GRID_SIZE; j++) 
       { 
        var tf:TextField = new TextField(); 
        var pos:Number = i*GRID_SIZE + j; 
        tf.text = pos.toString(); 
        tf.type = TextFieldType.DYNAMIC; 
        tf.addEventListener(MouseEvent.MOUSE_DOWN, createMCHdlr(pos)); 
        addChild(tf); 
        tf.x = i*100; tf.y = j*100; 
       } 
      } 
     } 

     private function createMCHdlr(pos:Number):Function 
     { 
      var ret:Function = function(evt:MouseEvent):void 
      { 
       trace('pos: ' + pos); 
      }; 
      return ret; 
     } 
    } 
} 
1

通过使用匿名函数内部,从外部范围的变量你有大麻烦已关闭和内存泄漏:position用于function(e:MouseEvent),但它创建于function Grid(),因此它会服从function Grid()的更改。你正在处理你添加的256 function(e:MouseEvent),但无法删除,重载内存!

让我们重拍你的代码最简单的工作方式:

public static const GRID_SIZE:Number = 16; 
private var i:int; 
private var j:int; 

public function Grid() { 
    var functions:Object; 

    for (i = 0; i < GRID_SIZE; i++) { 
    for (j = 0; j < GRID_SIZE; j++) { 
     var button:GridButton = new GridButton(); 
     button.x = (i + 1) * button.width; 
     button.y = (j + 1) * button.height; 
     var position:Number = i * GRID_SIZE + j; 
     functions[position] = buttonClick(position); 
     button.addEventListener(MouseEvent.CLICK, functions[position]); 
     //button.removeEventListener(MouseEvent.CLICK, functions[position]); 
     addChild(button); 
    } 
    } 

    buttonClick(position:Number):Function { 
    return function(e:MouseEvent):void { 
     // Now you can use both unique "e" and "position" here for each button 
    } 
    } 
} 

既然你加入256名的听众,你需要存储每个不同的变量(属性functions[position]的名单为它写了),所以你可以安全删除每个后面以释放内存以您添加它们的相同方式。

这是从this answer详细阐述的。