2009-08-30 7 views
0

표준 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 값이 도착 추적에서 볼 것입니다 옆으로.

나는 그 부분을 고치는 방법을 이해하지 못한다. 나는 mousemove 이벤트를 버블시키는 라벨이라고 생각하지만, 그렇게하지 못하게하는 방법을 이해하지 못한다.
모든 의견을 크게 환영합니다!

답변

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; 
    }  
+0

당신은 if (e.target! = object) return을 추가해야한다는 것을 의미합니다. 함수의 맨 위에? 그렇게하면 객체를 전혀 드래그 할 수 없습니다. 그렇지 않으면 if (e.target! = this) return; 그럼 나는 물체가 아닌 배경 위로 움직여서 끌 수 있습니다. – melfar

+0

약간의 오해. 나는 비슷한 것을하기 위해 사용하는 코드를 추가했다. – Glenn

+0

"pointTo"기능을 사용하여 표류 이벤트의 좌표를 변환해야합니다. 예 : Label 컨트롤의 TextField 하위 – Glenn

관련 문제