事件未从AS3中的侦听器中删除

时间:2011-09-15 12:07:09

标签: actionscript-3 flash-cs5

我正在为我的Flash应用程序(AS3和Flash CS5)开发一个drag'n'clone功能。克隆是完美创建的,但是当我尝试拖动最近创建的克隆时,应用程序会创建一个新克隆(并允许我拖动它)。

我想删除此行为:只应拖放克隆,而不是克隆。我的代码是:

public class Car extends MovieClip
    {

        // imports...

        public function Car()
        {
            addListeners();
        }

        private function addListeners():void
        {
            this.addEventListener(MouseEvent.MOUSE_DOWN,clone);
        }

        private function clone(e:MouseEvent):void
        {
            // Clone the object
            var newcar = new e.target.constructor;
            newcar.graphics.copyFrom(this.graphics);
            newcar.x = this.x;
            newcar.y = this.y;

            this.parent.addChild(newcar);

            newcar.addEventListener(MouseEvent.MOUSE_MOVE,dragCar);
            newcar.addEventListener(MouseEvent.MOUSE_UP,dropCar);
        }

        private function dragCar(e:MouseEvent):void
        {
            e.target.startDrag();
        }

        private function dropCar(e:MouseEvent):void
        {
            e.target.stopDrag();

                    // This line doesn't remove the event, and I don't know why
            e.currentTarget.removeEventListener(MouseEvent.MOUSE_DOWN,clone);

            e.target.removeEventListener(MouseEvent.MOUSE_MOVE, dragCar);
            e.target.removeEventListener(MouseEvent.MOUSE_UP,dropCar);

        }

    }

我希望有人可以帮助我。谢谢!

1 个答案:

答案 0 :(得分:1)

在这里,当您在clone函数中创建Car的新实例时,将调用该新Car对象的构造函数,然后调用addListeners()并且克隆具有MOUSE_DOWN事件侦听器,该侦听器再次克隆克隆。这就是为什么你有你描述的问题。

要避免这种情况,您需要在克隆功能中添加以下行(这不起作用,请参阅下面的编辑

newcar.removeEventListener(MouseEvent.MOUSE_DOWN,clone);

这将从克隆的(新)Car实例中删除clone事件侦听器,并避免再次克隆。

同样要开始拖动,你应该在MOUSE_DOWN而不是MOUSE_MOVE中进行。

<强>更新
好的,我看到,对于克隆,不再调用MOUSE_DOWN,因此需要使用MOUSE_MOVE。因此,在这种情况下,我会删除侦听器主体中的MOUSE_MOVE侦听器,以便只调用一次。

<强>更新
这似乎删除了事件监听器。

newcar.removeEventListener(MouseEvent.MOUSE_DOWN, newcar.clone);

您必须引用newcar实例的克隆方法newcar.clone来删除事件侦听器。

工作代码
以下代码工作得很好

package{
    import flash.display.MovieClip;
    import flash.events.*;
    public class Car extends MovieClip
    {
        public function Car()
        {
            addListeners();
        }

        private function addListeners():void
        {
            this.addEventListener(MouseEvent.MOUSE_DOWN,clone);
        }

        private function clone(e:MouseEvent):void
        {
            // Clone the object
            var newcar = new e.target.constructor;
            newcar.graphics.copyFrom(this.graphics);
            newcar.x = this.x;
            newcar.y = this.y;

            this.parent.addChild(newcar);

            // remove the clone listener
            newcar.removeEventListener(MouseEvent.MOUSE_DOWN, newcar.clone);

            // add dragging listeners
            newcar.addEventListener(MouseEvent.MOUSE_MOVE, dragCar);
            newcar.addEventListener(MouseEvent.MOUSE_UP, dropCar);

            // this is used for dragging the clone
            newcar.addEventListener(MouseEvent.MOUSE_DOWN, dragCar);
        }

        private function dragCar(e:MouseEvent):void
        {
            // if a MOUSE_MOVE event listener is registered remove it
        if(e.target.hasEventListener(MouseEvent.MOUSE_MOVE))
            e.target.removeEventListener(MouseEvent.MOUSE_MOVE, dragCar);
            e.target.startDrag();
        }

        private function dropCar(e:MouseEvent):void
        {
            e.target.stopDrag();

            // do not remove the listener if you want the clone to be dragable
            // e.target.removeEventListener(MouseEvent.MOUSE_UP,dropCar);
        }
    }
}

保持克隆可拖动
为此,我在上面的代码中添加了一个用于拖动克隆的MOUSE_DOWN事件监听器

newcar.addEventListener(MouseEvent.MOUSE_DOWN, dragCar);

并在e.target.removeEventListener(MouseEvent.MOUSE_UP,dropCar);

中注明了dropCar

在删除MOUSE_MOVE侦听器之前还添加了一个Check,看它是否存在,因为此函数稍后也会被MOUSE_DOWN调用。

相关问题