Have you ever wanted to prevent a JavaScript event from firing when it has been bubbled up from a child element? For example, let's say you have an onMouseOver event for a parent element. Anytime the mouse moves over any of the children elements, the parent's onMouseOver event will keep firing. Or, let's say you have an onMouseDown event on a parent and another on its child. Both onMouseDown events will fire when someone clicks the child. Sometimes this can be a real pain.
Anyway, enough examples, let's look at a way to avoid this. We need a way to fire an event only when the element with the event handler is the target element of the event. Here's the solution event handler:
function eventHandler(e) {
e = e || window.event;
var target = e.srcElement || e.target;
if (target != this) return;
// the rest of the function
}
Simple enough, once we have the code. Let's look at what it does.
First, we find the event object. In Firefox and Safari, it's a parameter to the function. In Internet Explorer, it's in window.event.
Having that, we need to find the target in the event object. This is the first element the event fires on, the inner-most or top-most element. In Safari and Firefox, it's target, but in Internet Explorer it's srcElement.
Finally, we will compare against the element the event is attached to. The element the event handler is attached to can be accessed easily with the this variable.
For more information on event handlers, I highly recommend the excellent resources at QuirksMode:
Update: you need to do a little bit more if you are dealing with mouseout events. If you move the mouse into a child, this triggers the mouseout event on the parent. In this case, the target will match the parent. So, you'll also have to get the 'related' element (the child) and make sure the target isn't one of the ancestors. Here is the updated function for mouseout events:
function mouseOutEventHandler(e) {
e = e || window.event;
var target = e.srcElement || e.target;
if (target != this) return;
var related = e.relatedTarget || e.toElement;
while (related != this && related.nodeName != 'BODY')
related = related.parentNode;
if (related == this) return;
// the rest of the function
}
Special thanks to QuirksMode's Mouse Events page for helping me figure out that one!
I'm currently using onmouseover(param1, p2) inside a div tag, but I would like to use your code to solve the bubbling problem.
However I cannot see how to pass my parameter to your mouseOutEventHandler(e) so that the "rest of function" can do what I need.
Nice web site. Thanks.
Steve
I can't seem to burst the event bubble, I've spent countless hours on my specific scenario without avail. Please help.
I tried the code above but I get a strange result. The code below 'the rest of the function' only fires when the mouse leaves the right side of the div.
I have a div with other elements in it, I need to fire the mouseover/mouseout events only when I leave the whole div that contains everything else.
Regards,
Diego
Here's another easy way to stop the event from bubbling from the event handler:
function doSomething(e)
{
if (!e) var e = window.event;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
}