Imagine I have the following elements:
+------------------+
| |
| +----------------+
| | |
| | |
| +----------------+
| |
+------------------+
The inner element has positioning that mean it can visually sit outside of its parent, and I put an event listener on the parent like such:
parent.addEventListener('mouseover', function(e) {
// log mouse is over me
}, false);
If I mouse directly over the parent from the bottom, I get a direct event, but because of event routing if I mouse over from the side (hitting the child first), I'll also receive the event from the child as it bubbles up.
If I keep going left until I'm out of the child element and in the parent space, I'll get a direct event, if I go right again, I'll get another bubbled event from the child element.
This is by design and the design is absolutely fine, however- if I want to do a SINGLE action when the mouse overs me (including my child items), I need to do some extra work to block events I'm not interested in.. for example, this would work:
var isOver = false;
parent.addEventListener('mouseover', function(e) {
if (isOver) return;
isOver = true;
// log mouse is over me
}, false);
parent.addEventListener('mouseout', function(e) {
if (e.relatedTarget == this || e.relatedTarget.isDescendantOf(this)) return;
isOver = false;
// log mouse is leaving me
}, false);
Essentially the code has a state variable to determine if the mouse has 'overed' the parent (either via its child or not), and if the event fires again whilst 'overed' those events are ignored.. we also capture the mouse out event and ask it.. is the relatedTarget (the target you are about to enter) ME? (the parent), or an eventual child of ME? if so, then don't do anything.. otherwise set the 'overed' state to false.
So that code actually works, but imagine I cannot use the relatedTarget property to determine the next target, how would you go about doing this behavior?
I hope that makes sense, I have the feeling theres not enough context in the events to do it without relatedTarget but felt there might well be an angle regarding changing behavior on the eventPhase property (to determine if the event is direct or bubbled).
Also I'm not looking for answers saying 'this won't work in ie, yadda yadda'.. I'm working against w3c event spec browsers only right now.
Thanks in advance, Stephen.
Edit, just to clarify, I want the events to happen as if I have a single element that looked like this (if the element was actually as above example):
+------------------+
| |
| +--+
| |
| |
| +--+
| |
+------------------+