我无法找到更好的标题来描述我的问题。
我想实现这个目标:
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上移动。也许我可以使用像“这个”或“自我”这样的东西......
有什么建议吗?
答案 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
,而是我们添加了事件监听器。