To pass a parameter to event listener in AS3 the simple way… does it exist?

前端 未结 5 1802
轻奢々
轻奢々 2020-11-28 04:00

Expected / pseudo example:

stage.addEventListener(MouseEvent.CLICK, onClick.someWayToPassParameters(true, 123, 4.56, "string"));
function onClick(e:         


        
5条回答
  •  醉话见心
    2020-11-28 04:49

    Out of the box: it only takes 2 extra lines of elegant code to solve this ancient puzzle.

    stage.addEventListener(MouseEvent.CLICK, onClick(true, 123, 4.56, "string"));
    function onClick(b:Boolean, i:int, n:Number, s:String):Function {
      return function(e:MouseEvent):void {
        trace("Received " + b + ", " + i + ", " + n + " and " + s + ".");
      };
    }
    

    But most importantly, you will very likely need to remove the listener later to free resources, so +1 line to store it in a variable:

    var functionOnClick:Function = onClick(true, 123, 4.56, "string");
    stage.addEventListener(MouseEvent.CLICK, functionOnClick);
    function onClick(b:Boolean, i:int, n:Number, s:String):Function {
      return function(e:MouseEvent):void {
        trace("Received " + b + ", " + i + ", " + n + " and " + s + ".");
      };
    }
    

    And you'll be able to remove it normally:

    trace("Before: " + stage.hasEventListener(MouseEvent.CLICK));
    stage.removeEventListener(MouseEvent.CLICK, functionOnClick);
    trace("After: " + stage.hasEventListener(MouseEvent.CLICK));
    

    Here's a more elaborated, dynamic example to prove its use:

    function onClick(s:String):Function {
      return function(e:MouseEvent):void {
        trace("The square " + s + " at x = " + e.currentTarget.x + "px was clicked");
      };
    }
    var myFunctions:Array = new Array();
    for (var i:int = 0; i < 10; i++) {
      myFunctions.push(onClick("#" + (i+1)));
    }
    for (i = 0; i < myFunctions.length; i++) {
      var square:Sprite = new Sprite();
      square.name = "sqr" + i;
      square.addChild(new Bitmap(new BitmapData(20, 20, false, 0)));
      square.x = 5 + 25 * i;
      square.addEventListener(MouseEvent.CLICK, myFunctions[i]);
      stage.addChild(square);
    }
    

    No properties through dynamic objects, no custom class, no loose functions, no scope overlap. Just what logic expects it to be: you're simply passing arguments to it.

    And to remove every listener properly, you can do it like this later:

    for (i = 0; i < myFunctions.length; i++) {
      square = stage.getChildByName("sqr" + i) as Sprite;
      trace("Before (#" + (i+1) + "): " + square.hasEventListener(MouseEvent.CLICK));
      square.removeEventListener(MouseEvent.CLICK, myFunctions[i]);
      trace("After (#" + (i+1) + "): " + square.hasEventListener(MouseEvent.CLICK));
      stage.removeChild(square);
    }
    

    IMHO this is the simplest yet most solid way to do it.

提交回复
热议问题