In Twitterified Client v1, one of the features I really wanted available right off the bat, was that when a user moves their mouse pointer over a twitterer’s avatar, an overlay image is displayed. This image is a menu of sort, allowing the user to send a direct message, a reply or access a more advanced menu. Of course, when the mouse pointer exists the avatar’s region, the overlay image needs to quietly go. Being the Flex newbie that I am, I thought that a straightforward implementation would work:
_imageOverlayPanel.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut); |
In onMouseOut(), I would detach _imageOverLayPanel, remove the listener, and move foward. Unfortunately, when moving my mouse around at a reasonably fast speed, I found out that the overlay panel did not go away, and after a while I had several avatars “polluted” by that overlay panel. I started “tracing” the MOUSE_OUT event and found out that, at least in AIR applications, there is no guarantee that such an event will be triggered. Ouch.
I experimented with, instead, using a timer that would kick in every 500ms and check whether the mouse pointer was still in the avatar’s region. It worked very well but felt a bit clunky and there was a risk of race condition with mouse events.
In the end, I settled for an approach using MOUSE_MOVE, which feels “cleaner” and works almost as well as the timer method:
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMovePossiblyOut); |
private function onMouseMovePossiblyOut(event:MouseEvent):void { if(!_imageOverlayPanel.parent) return; var pt:Point = new Point(event.stageX, event.stageY); pt = _imageOverlayPanel.globalToLocal(pt); if(pt.x < 0 || pt.y < 0 || pt.x > _imageOverlayPanel.width || pt.y > _imageOverlayPanel.height) { _imageOverlayPanel.parent.addEventListener(MouseEvent.MOUSE_OVER, onImageMouseOver); // innerWrapper resumes listening to mouse_over events _imageOverlayPanel.parent.removeChild(_imageOverlayPanel); // overlay panel is detached from innerWrapper } } |
Note that the trick, here, is that I add my mouse listener to the stage rather than the image overlay itself. This allows me to receive mouse events that happen outside the overlay’s region; they are the ones I am interested in.
If you enjoyed this post, make sure you subscribe to my RSS feed!






Maybe you should use MouseEvent.ROLL_OUT instead of MOUSE_OUT?
Thank you so much, I had this exact same problem. I tried ROLL_OUT, I tried using a global manager to it would reset them etc. The mouse move solution is by far the best.
Hi,
I like your solution but there are unclear for me the following lines of code. Could you give some more explanation to them?
_imageOverlayPanel.parent.addEventListener(MouseEvent.MOUSE_OVER, onImageMouseOver); // innerWrapper resumes listening to mouse_over events
How did you create _imageOverlayPanel panel?
_imageOverlayPanel.parent.removeChild(_imageOverlayPanel); // overlay panel is detached from innerWrapper
Best Regards
Chris
Hi,
Not much space in the form messed up everything in my previous post, so here I go again.
I like your solution but there are unclear for me the following lines of code. Could you give some more explanation to them?
_imageOverlayPanel.parent.addEventListener(MouseEvent.MOUSE_OVER, onImageMouseOver); // innerWrapper resumes listening to mouse_over events
_imageOverlayPanel.parent.removeChild(_imageOverlayPanel); // overlay panel is detached from innerWrapper
How did you create _imageOverlayPanel panel?
Best Regards
Chris
@Chris –
_imageOverlayPanel is a Canvas. You can browse the source code here: http://github.com/Fusion/Twitterified/blob/master/src/com/voilaweb/tfd/StatusRow.as