使用鼠标事件复制拖放的问题

时间:2009-08-30 07:36:21

标签: flex

我想用自己的例程复制标准的startDrag / stopDrag事件来稍微改变一下,我遇到了某种事件传播或冒泡问题。这是我的代码:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
                mouseDown="mouseDown = true" mouseUp="mouseDown = false"
                mouseMove="mouseMove(event)">

  <mx:Script>
    <![CDATA[
        private var mouseDown:Boolean = false;
        private var oldMouseX:int = 0, oldMouseY:int = 0;

        private function mouseMove(e:MouseEvent):void {
            if (mouseDown) {
                object.x += (e.localX - oldMouseX);
                object.y += (e.localY - oldMouseY);
            }

            oldMouseX = e.localX;
            oldMouseY = e.localY;

            trace(e.localX);
        }
    ]]>
  </mx:Script>  

  <mx:Label id="object" text="Drag me" />

</mx:Application>

此代码的问题在于,当您将对象向右拖动时,您将在跟踪中看到偶尔会有一些随机的localX值到达那里,从而导致对象从一侧到另一侧抖动。

我不明白如何修复那个部分,我认为它是使鼠标移动事件起泡的标签,但我不明白如何阻止它这样做。
非常感谢任何建议!

1 个答案:

答案 0 :(得分:2)

跟踪您关注的目标,并直接从中收听事件。所以在你的mousemove函数中,检查e.target ==你的对象。在这种情况下,应用程序。您将从子组件中冒出杂散事件。

    public static function smoothDrag(pressEvent:MouseEvent, dragTarget:DisplayObject = null, done:Function=null, move:Function = null, parent:DisplayObject = null):void {
        var target:DisplayObject = dragTarget;
        parent = parent || target.parent;
        var eventParent:EventDispatcher = target.stage || parent;

        var moveFunc:Function = move;
        var doneFunc:Function = done;

        var startPoint:Point = MouseHelpers.pointTo(pressEvent.localX, pressEvent.localY, pressEvent.target as DisplayObject, parent);
        startPoint.x -= target.x
        startPoint.y -= target.y;

        var setPosition:Function = function(e:MouseEvent):void 
        {
            e.stopImmediatePropagation();
            var p:Point = MouseHelpers.pointTo(e.localX,e.localY, e.target as DisplayObject, parent);
            target.x = p.x - startPoint.x;
            target.y = p.y - startPoint.y;

            if (moveFunc != null) {
                moveFunc();
            }
        }

        var stopMove:Function = function(e:MouseEvent):void {
            e.stopImmediatePropagation();
            eventParent.removeEventListener(MouseEvent.MOUSE_MOVE, setPosition, true);
            eventParent.removeEventListener(MouseEvent.MOUSE_UP, stopMove, true);
            eventParent.removeEventListener(MouseEvent.ROLL_OVER, EventHelpers.stop, true);
            eventParent.removeEventListener(MouseEvent.MOUSE_OVER, EventHelpers.stop, true);

            if (doneFunc != null) {
                doneFunc(e);
            }
        }
        eventParent.addEventListener(MouseEvent.ROLL_OVER, EventHelpers.stop, true, 0, true);
        eventParent.addEventListener(MouseEvent.MOUSE_OVER, EventHelpers.stop, true, 0, true);
        eventParent.addEventListener(MouseEvent.MOUSE_MOVE, setPosition, true, 0, true);
        eventParent.addEventListener(MouseEvent.MOUSE_UP, stopMove, true, 0, true);
    }


    /**
     *  Translate a point from one object's reference into another. Best used when you have a descendant object x/y and you
     *  want to get that position relative to an ancestor. Uses the localToGlobal/globalToLocal style. 
     **/
    public static function pointTo(fromX:Number, fromY:Number, src:DisplayObject, dest:DisplayObject):Point {
        var p:Point = new Point(fromX, fromY);
        if(src != dest) {
            p = src.localToGlobal(p);
            p = dest.globalToLocal(p);
        }
        return p;
    }