for循环中的AS3个别事件监听器

时间:2011-12-30 14:57:25

标签: actionscript-3 for-loop event-listener

我无法找到更好的标题来描述我的问题。

我想实现这个目标:

for(var i:int = 0; i < 10; i++) {
     var mc:MovieClip = new MovieClip();
     mc.addEventLister(MouseEvent.MOUSE_OVER, function() {
        mc.y=-20;
     });
}

我的问题是mc总是引用for循环中创建的最后一个mc,因此创建的第一个mc导致最后一个mc在mouseover上移动。也许我可以使用像“这个”或“自我”这样的东西......

有什么建议吗?

2 个答案:

答案 0 :(得分:4)

有很多方法可以解决这个问题,你可以使用事件对象

for(var i:int = 0; i < 10; i++) {
     var mc:MovieClip = new MovieClip();
     mc.addEventLister(MouseEvent.MOUSE_OVER, function(e) {
        MovieClip(e.currentTarget).y=-20;
     });
}

或者您可以使用匿名闭包来创建稳定的变量范围:

for(var i:int = 0; i < 10; i++) {
     (function(mc:MovieClip):void  {
        mc.addEventLister(MouseEvent.MOUSE_OVER, function(e) {
            mc.y=-20;
        });
     })(new MovieClip());
}

或者执行相同操作的命名函数:

function attachListenerTo(mc:MovieClip):void {
    mc.addEventLister(MouseEvent.MOUSE_OVER, function(e) {
        mc.y=-20;
    });
}

for(var i:int = 0; i < 10; i++) {
     attachListenerTo(new MovieClip());
}

或者您可以创建MovieClip的子类并在绑定的上下文中附加事件侦听器:

public dynamic class ChildClass extends MovieClip {
    public function ChildClass() {
        this.addEventListener(MouseEvent.MOUSE_OVER, handleOver);
    }

    private function handleOver(e:MouseEvent):void {
        this.y = -20;
    }
}

// And then

for(var i:uint=0;i<10;i++) {
    var mc:MovieClip = new ChildClass();
}

修改

关于为什么您的第一个版本失败的简短说明,ActionScript没有块范围(与C#等其他语言不同)并使用变量提升。这意味着行var mc:MovieClip不在您认为的位置。实际上,只有一个名为mc的变量,它与功能范围绑定,这意味着通过循环的每次迭代,您只需重新分配名为mc的单个变量。由于您正在创建一个匿名函数作为处理程序,因此它也绑定到与mc相同的范围。这就是mc始终引用循环中的最后一个MovieClip的原因,当调用任何这些闭包时,它在循环运行完毕并且mc仍然指向最后一个闭包之后很久。

答案 1 :(得分:2)

你想做这样的事情:

for(var i:int = 0; i < 10; i++) {
     var mc:MovieClip = new MovieClip();
     mc.addEventLister(MouseEvent.MOUSE_OVER, function(evt:Event) {
        evt.currentTarget.y=-20;
     });
}

请注意,我没有使用mc我使用事件的currentTarget,而是我们添加了事件监听器。