2009-08-30 8 views
0

Je veux répliquer les événements standard startDrag/stopDrag avec ma propre routine pour modifier un peu les choses, et je rencontre un problème de propagation ou de bullage d'un événement. Voici mon code:Problèmes de réplication du glisser-déposer avec les événements souris

<?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> 

Le problème avec ce code est que lorsque vous faites glisser l'objet vers la droite, vous verrez dans la trace que de temps en temps quelques valeurs localX aléatoires arrivent là-bas, ce qui dans l'objet saccades d'un côté à côté.

Je ne comprends pas comment réparer cette partie, je pense que c'est l'étiquette qui provoque la bulle de l'événement mousemove, mais je ne comprends pas comment l'empêcher de le faire.
Toutes les suggestions sont grandement appréciées!

Répondre

2

Suivez la cible qui vous intéresse et n'écoutez que les événements directement à partir de celle-ci. Donc, dans votre fonction mousemove, vérifiez e.target == votre objet. Dans ce cas, l'application. Vous obtiendrez des événements parasites qui bouillonnent à partir des sous-composants.

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

Vous voulez dire que je devrais ajouter if (e.target! = Object) return; sur le dessus de la fonction? Si je le fais, l'objet ne peut pas être déplacé du tout. Sinon, si j'ajoute if (e.target! = This) return; alors je peux glisser en se déplaçant sur l'arrière-plan et non sur l'objet. – melfar

+0

Léger malentendu. J'ai ajouté le code que j'utilise pour faire une chose similaire. – Glenn

+0

Vous devez utiliser la fonction "pointTo" pour traduire les coordonnées des événements parasites. par exemple, l'enfant TextField du contrôle Label. – Glenn

Questions connexes