Detecting mouse move and release on a locked draggable object
I'm making a custom slider component. The head (the thing that you drag) is programmed like this:
head.addEventListener(MouseEvent.MOUSE_DOWN, function():void {
head.startDrag(false, new Rectangle(stubDiv,0,width - stubDiv - ((levels-maxLevel)*stubDiv),0));
});
head.addEventListener(MouseEvent.MOUSE_MOVE, function():void {
updateLevel();
});
head.addEventListener(MouseEvent.MOUSE_UP, function():void {
head.stopDrag();
setHeadPos();
});
Because the head is constrained to the area of the slider bar, the mouse can move away from it. If that happens, the object is still being dragged, but it doesn't receive MOUSE_MOVE
events, nor the MOUSE_UP
event if the mouse is released.
What's the bes开发者_C百科t solution?
Instead of calling updateLevel() in head's MOUSE_MOVE event, call it in the head's ENTER_FRAME event:
head.addEventListener(MouseEvent.MOUSE_DOWN, function():void {
head.startDrag(false, new Rectangle(stubDiv,0,width - stubDiv - ((levels-maxLevel)*stubDiv),0));
head.addEventListener(Event.ENTER_FRAME, function():void { updateLevel(); });
});
head.addEventListener(MouseEvent.MOUSE_UP, function():void {
head.stopDrag();
head.removeEventListener(Event.ENTER_FRAME, function():void { updateLevel(); });
setHeadPos();
});
head.Stage.addEventListener(Event.MOUSE_LEAVE, function():void {
head.stopDrag();
head.removeEventListener(Event.ENTER_FRAME, function():void { updateLevel(); });
setHeadPos();
});
I worked on a similar feature before and I also needed to handle Stage's Mouse_Leave. Depending on your requirement, you might also want to add MouseEvent.MOUSE_OUT to head
In AS3 this is handled by adding a MouseEvent listener to the stage listening for the MOUSE_UP event.
head.addEventListener(MouseEvent.MOUSE_DOWN, _handleDown);
function _handleDown($evt:MouseEvent):void {
// add a MouseEvent.MOUSE_UP listener to the stage
stage.addEventListener(MouseEvent.MOUSE_UP, _handleUp);
head.removeEventListener(MouseEvent.MOUSE_DOWN, _handleDown);
head.addEventListener(MouseEvent.MOUSE_MOVE, _handleMove);
head.addEventListener(MouseEvent.MOUSE_UP, _handleUp);
head.startDrag(false, new Rectangle(stubDiv,0,width - stubDiv - ((levels-maxLevel)*stubDiv),0)
}
function _handleMove($evt:MouseEvent):void {
updateLevel();
}
function _handleUp($evt:MouseEvent):void {
// remove the MouseEvent.MOUSE_UP listener from the stage
stage.removeEventListener(MouseEvent.MOUSE_UP, _handleUp);
head.removeEventListener(MouseEvent.MOUSE_UP, _handleUp);
head.removeEventListener(MouseEvent.MOUSE_MOVE, _handleMove);
head.addEventListener(MouseEvent.MOUSE_DOWN, _handleDown);
head.stopDrag();
setHeadPos();
}
As you can see, as a matter of style, I avoid using anonymous functions in my event listeners. This allows for far more flexibility in most cases, and in my opinion, is far easier to read.
As far as your other issue, not having the "scroll handle" react to MOUSE_MOVE events... do you want it to still react even after you have rolled away from the handle? Depending on how you want this to work it could be done a variety of ways.
Please clarify exactly what behavior you are looking for.
精彩评论