Thoughtprocess Interactive — Web Design & Interactive 314-282-3699

tpi blog

thoughts on web development & digital marketing

The power and genius of mouseChildren and mouseEnabled.

I admit, this post will be useless for most readers of this blog. But if you happen to be an Actionscript programmer… I had a minor epiphany today from which you might benefit.

Since I started writing AS3 code, I’ve generally viewed the mouseChildren and mouseEnabled properties of the InteractiveObject class (and by extension the Sprite class) as relatively superfluous. They existed as little more than a recourse for when something accidentally got ‘in between’ the mouse and a button that needed to be pressed. And in a sense that is true. But I realized today that those crafty AS3 creators had bestowed upon me a much more substantial tool than I’d first realized.

Fundamentally, these two properties are straightforward. Setting a Sprite’s mouseEnabled property to false tells that Sprite to not bother interacting with the mouse. In other words, to stop dispatching MouseEvents such as MouseEvent.CLICK. Likewise, setting a Sprite’s mouseChildren property to false tells the children of that Sprite to stop dispatching MouseEvents. By default, both properties are set to true.

The magic comes by virtue of the fact that these two properties work independently of each other. If a Sprite has children, setting that Sprite’s mouseEnabled to false does not prevent the Sprite’s children from dispatching MouseEvents. Similarly, setting the Sprite’s mouseChildren to false doesn’t prevent the sprite itself from dispatching MouseEvents. Why is this cool? Let me count the reasons:

  • Sprite ‘flattening’. It used to drive me nuts that that a button made of multiple sub-elements (label, hilight, border, icon, etc) would have an indeterminate MouseEvent ‘originator’. That is, the target property of the MouseEvent would be ‘label’ or ‘highlight’ or whatever depending on the exact pixel over which the mouse rested, rather than simply ‘myButton’. I found myself putting invisible ‘mousetrap’ layers in my buttons to sit on top of everything to fix this. It turns out I don’t need to. By setting myButton.mouseChildren = false all the button parts become a single unit, collectively dispatching MouseEvents with a target of ‘myButton’.
  • Group disabling. Need to disable a whole group of buttons? Make them siblings and set the parent Sprite’s mouseChildren to false.
  • Event-bubbling simplification. By setting a container Sprite’s mouseEnabled = false but leaving mouseChildren = true, you prevent the ‘middleman’ from sending unnecessary MouseEvents to high-level MouseEvent handlers. Imagine a calculator, with multiple keys, a display screen, a surrounding ‘case’, a nice little Texas Instruments logo, whatever. If I add a MouseEvent.CLICK listener to the high-level calculator object, I will receive all of the various key clicks, but I will also receive events from the other child elements… the display, the case, the logo. Even if I set those elements to mouseEnabled = false, the calculator Sprite itself will still trigger its own MouseEvents when I roll over them. By following up with calculator.mouseEnabled = false, the high-level listener will now only receive events from the children that matter, and will not be encumbered with ‘false positives’.

Given this greater understanding, I almost wonder why the AS3 creators chose to set the default of mouseEnabled to true. After all… aren’t there generally far more ‘passive’ display objects on the stage than interactive ones? I’m sure they had a reason, and it’s probably one that I could find by Googling around a bit… but enough is enough. Hardcore geek session over.

14 thoughts on “The power and genius of mouseChildren and mouseEnabled.

  1. Yes, these are handy but bear in mind that you can still access the buttons using the keyboard. As the properties names specify they purely disable the mouse interaction.

  2. Hi, just wanted to thank you for this post. I was having an issue, found your site, and was able to fix the problem. I kept wondering why just the mouseEnabled set to false alone would not work.

  3. Hi.
    So…can you answer this one?

    I have a movieclip with 3 children: a Sprite as background, a dynamic TextField and a Button. I want to be able to add MOUSE_OVER eventlisteners to the movieclip, while keeping the handcursor when I roll over the textfield and CLICK events from the button.

    The thing is, if you set:

    movieclip.mouseEnabled = true;
    movieclip.mouseChildren = false; //to keep the handcursor while over ther textfield

    .. the button will not work (mouseChildren is false).

    If you set movieclip.mouseChildren = true then the button will work BUT handcursor will not show when rolling over the textfield.

    Any ideas? 😛 thanks!

  4. Hey Edd, if I understand your description correctly, the problem is that the TextField is still mouseEnabled, and therefore when the mousepointer moves onto it, you have ‘exited’ the containing MovieClip in terms of mouseEvent detection. So, the solution would be:

    myOuterMovieClip.mouseEnabled = true;
    myOuterMovieClip.mouseChildren = true;
    myOuterMovieClip.myNestedTextField.mouseEnabled = false;

    Once you have turned off mouseEnabled on the TextField, it essentially ‘flattens’ into it’s parent Movieclip’s mouseEvent detection.

  5. Thanks dude! This was driving me nuts. An artist had provided me with beautiful multi-layered buttons, but they would not pass the event – mouseChildren = false did it!

    Those darn mouse children!

  6. Also would like to add that you must set “mouseEnabled = false” to all parent clips in order to set that property on a child movieclip.

    Eg. Make myMc.bg not register mouse clicks.

    // Doesn’t work
    myMc.addChild(bg);
    myMc.bg.mouseEnabled = false;

    // Works!
    myMc.addChild(bg);
    myMc.mouseEnabled = false;
    myMc.bg.mouseEnabled = false;

  7. Nice post, very informative and I like your blog for it’s many articles on as3 bugbears which are hidden from mortals, avoided by Adobe and which pounce like ninja’s when least expecting…

    Θ)

  8. I can’t find an answer to a simple issue. I have a shell movieclip that loads a subclip. This is for a banner. The shell has a clicktag button that covers the entire banner. The subload has a small button in it that dispatches an event. I need them both to be clickable. Normally I would drag the small button on a layer on top of the clicktag but since they are in seperate files I can’t do that. Is there a way to have both buttons enabled and clickable? thanks!

    1. @astorria:

      If you’re working in AS3, and you’re using a Loader instance to load the sub-movie, you can do it like this:


      var myLoader:Loader = new Loader(); // this represents your loader instance
      stage.addChild(myLoader);

      By using the addChild method of the stage, you are adding your Loader instance (and the movie it contains) to the front of the stage’s display list, which will put it in front of the clickTag. Of course, that brings the ENTIRE subclip to the front, which may not be what you intend. In that case, you’d have to ‘drill down’ into the subclip to grab the DisplayObject instance that represents your button, and add THAT to the stage. Something like this:


      function onloadingComplete(e:Event):void {
      stage.addChild(e.target.content.myButton);
      }
      var myLoader:Loader = new Loader();
      myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onloadingComplete);
      myLoader.load(new URLRequest("mySubClip.swf"));

  9. hi, can you please give me an code example? I’m building a map with flash, the mc name is map and inside it, i put a button.. but when i test the movie, button doesnt working.. sorry i’m newbie in flash.. please help me..

Leave a Reply

Your email address will not be published. Required fields are marked *

get in touch

comments? questions? we'd love to hear from you.

Whether you'd like to discuss a project, get a little insight, or make a suggestion —
drop us a note using the form below, or give us a call at 314-282-3699314-282-3699.


Ready to get your project started? Request a quote and we'll give you a detailed estimate.