Thursday, April 2, 2009

Problems with jQuery mouseover / mouseout events

Today I have a quick note for you that will probably save you time someday. Basically it’s a workaround for a bug when you have parent element with children elements and parent element has mouseover or mouseout event. Moving your mouse over children elements may fire mouseout event of their parent. This is caused by event bubbling / propagation and if you would like to have a quick solution just read the solution at the bottom of this post. If you would like to understand it in more details please search Google for event propagation.

The problem:

When you have mouseover and mouseout events bound to some element on you page with children elements. Hovering over children element fires parent’s mouseover and/or mouseout event.

The solution:

The solution to this error is to use mouseenter and mouseleave events instead of mouseover and mouseout.

The reason:

This solution works because mouseover and mouseout events do not bubble from child to parent element.

32 comments:

  1. preventdefault & stoppropagation doesnt work?

    ReplyDelete
  2. I think this is intended behaviour since jQuery 1.3:

    When you trigger events by using e.g. .click() events will bubble up through the DOM.

    http://docs.jquery.com/Events/trigger
    http://docs.jquery.com/Events/bind

    I haven't experimented with this feature although.

    ReplyDelete
  3. Ever heard of event bubbling/propagation? This is normal and expected behaviour. An event will bubble up through the DOM until it reaches the top or it's halted with "event.stopPropagation()"

    ReplyDelete
  4. @Astfgl, @James, Thanks for your replies. I know that you are referring to event bubbling here.

    Reading this post again, I now see that I have not made the main idea clear enough here. The main idea was that mouseenter and mouseleave events DO NOT BUBBLE!

    I will rewrite the post later this day and will try to make the main idea clearer.

    Thanks for your timely feedback. It's very much appreciated.

    ReplyDelete
  5. btw, use hover instead mouseouver, mouseout. its more clean

    $("selector").hover(function(){ /* mouseover */ }, function(){ / *mouseout */ });

    nd you can use the stoppropagation to prevent the events from parent objects

    ReplyDelete
  6. Ok, but what about the hover() function?
    Ignore it and use mouseenter and mouseleave?

    ReplyDelete
  7. @Carlos André Ferrari, @Barton, I totally agree that .hover() function is clearer to read and write your code, but in this article I am pointing out that:

    **QUOTE**
    This solution works because mouseover and mouseout events DO NOT BUBBLE from child to parent element.

    ReplyDelete
  8. Does it matter to anyone else that mouseenter and mouseleave are not standard events? To date, these custom events are only available in IE. Of course you could use jQuery's custom event mechanism to recreate them, but for that amount of effort you could just roll your own solution using preventDefault or stopPropagation.

    ReplyDelete
  9. The fact that mouseover and mouseout don't bubble is not a particularly interesting observation. If you're using jQuery, there's rarely good reason to bother with mouse* events to begin with.

    You shouldn't recommend that people use the non-standard mouseenter and mouseleave. Everyone working in javascript should understand event propagation and deal with it properly.

    ReplyDelete
  10. Hi:

    I have started learning jquery from scratch and tried to show an alert box on mouseover event but not working i tried this mouseenter and mouseleave function which is suggested in this article but these are also not working.

    For "onmouseover" the "hover" event is working.
    But i have not got any solution for onmouseout event.

    ReplyDelete
  11. @twinkle, why don't you use .hover() [http://docs.jquery.com/Events/hover] function?!

    $("#box").hover(
    function () {
    // fired on mouseover
    },
    function () {
    // fired on mouseout
    }
    );

    ReplyDelete
  12. Hi there,

    Just wanted to say thanks for the post - totally overlooked the mouseenter/leave events and this was the exact solution I needed.

    @those who said something about non/standard events - the post title says 'JQuery' so your comments are irrelevant.

    @the guy who said 'for that amount of effort you could just roll your own solution' - '$("#id").mouseenter()' vs. manually handling propagation? Why bother using a framework at all then? :)

    @those who suggested using hover - your comments are irrelevant to this post.

    @those who suggested the author doesn't understand event bubbling/propagation - he explains it fine so chill.

    Really just kinda tired of hearing ego-driven comments when there's nothing egregiously wrong with this post that's just out to help people.

    Have a happy code-filled day.

    Let's all advocate a constructive, a-hole-free dev community.

    ReplyDelete
  13. hi,

    just wanna thank you about this solution, it's fixed my thumbnail gallery...

    ReplyDelete
  14. Most Verbose Anonymous:

    Please be aware that mouseenter/mouseleave are -not- jquery features, but rather features of Internet Explorer and will not work on other browsers.

    ReplyDelete
  15. Thanks a lot !
    Ben

    ReplyDelete
  16. OMG thanks you so much ...

    Struggling for hours with the problem, now sorted :-)

    ReplyDelete
  17. Great advice, you really did save me some time! Thank you!

    ReplyDelete
  18. Wonderful. Was already lost in if/else constructions to check for parents and what not as the mouseout got triggered by my links within the toggled div.

    This made my headache go away.

    Thanks.

    ReplyDelete
  19. Please stop with the misinformation:

    stopping propagation on mouseover does NOT achieve the same as mouseenter... sample code/prove here:

    http://jsbin.com/ezito/edit

    JT.

    ReplyDelete
  20. Actually, June13, both mouseenter and mouseleave -are- jquery features.

    documented here:
    http://brandonaaron.net/blog/2009/03/26/special-events
    linked from:
    http://docs.jquery.com/Events/jQuery.Event#event.type

    ReplyDelete
  21. Nice Post Dude Thank you very much

    ReplyDelete
  22. hi

    this is rohit.

    mouseout event & mouseleave event is not working in my jquery.

    so can you guys help me to solve this problem?

    ReplyDelete
  23. thanks very much

    ReplyDelete
  24. This indeed saved me some time, thank you very much!

    G

    ReplyDelete
  25. Thank you very much! The .hover() method was my savior :)

    ReplyDelete
  26. Thanks a lot!


    From now, i love mouseenter()

    ReplyDelete
  27. Thats what i exactly need !
    Thanks a lot ;)

    ReplyDelete
  28. Was going 15 minutes on this one and finally found your blog post. Fixed. I replaced .hover() with mouseenter() Thanks.

    ReplyDelete