faqts : Computers : Programming : Languages : JavaScript : Event handling

+ Search
Add Entry AlertManage Folder Edit Entry Add page to http://del.icio.us/
Did You Find This Entry Useful?

169 of 187 people (90%) answered Yes
Recently 10 of 10 people (100%) answered Yes

Entry

How can I distinguish onmouseover/out of child elements from those of the parent element (IE4 /NN6)?
Why does my layer's onmouseover/out fire when the mouse moves over a child element (IE4 /NN6)?
Why does my layer's onmouseover/out fire when the mouse moves over a child element (IE4 /NN6)?

Apr 26th, 2004 08:33
Daniel LaLiberte, Martin Honnen,


IE4+ and NN6+, Opera 7 (and probably any browser coming up and trying to
implement DOM Level 2) have so called event bubbling event handling
mechanism which means the parent element receives the events from child
elements (the event "bubbles up" from the child to the parent). For
example if you have
  <DIV ONMOUSEOVER="window.status = event.type"
      ONMOUSEOUT="window.status = event.type"
  >
  some content
  <A HREF="whatever.html">link</a>
  some content
  </div>
you will find that with IE4+ and NN6+ and Opera 7 mouseover fires first
but mouseout fires when the mouse moves over the link.  This means that 
the problem is not just about bubbling, because when you mouse the 
mouse over the link, you are not moving out of anything contained in 
the div nor are you moving out of the area contained by the div. A 
mouseout event fires simply because a mouseover event fires for another 
element.
To work around these problems there are, starting in IE4+, 
event.toElement, event.fromElement and element.contains. While NN6+ 
provides event.relatedTarget only, to use the following, you will need 
to implement contains yourself. So for IE4+
  <DIV ONMOUSEOVER="if (!this.contains(event.fromElement)) 
window.status = event.type"
      ONMOUSEOUT="if (!this.contains(event.toElement)) window.status = 
event.type;"
  >
is a way to fire event handling only when the mouse moves from outside 
over an element and from inside out of an element.  This is, for 
example, important when you want to hide layer onmouseout. For NN6+ and 
IE4+ and Opera 7 the following example contains a solution for the 
contains function and an example to use it:
<html>
<head>
<title>onmouseenter/leave for IE4+, Netscape 6+, Opera 7</title>
<script type="text/javascript">
function containsDOM (container, containee) {
  var isParent = false;
  do {
    if ((isParent = container == containee))
      break;
    containee = containee.parentNode;
  }
  while (containee != null);
  return isParent;
}
function checkMouseEnter (element, evt) {
  if (element.contains && evt.fromElement) {
    return !element.contains(evt.fromElement);
  }
  else if (evt.relatedTarget) {
    return !containsDOM(element, evt.relatedTarget);
  }
}
function checkMouseLeave (element, evt) {
  if (element.contains && evt.toElement) {
    return !element.contains(evt.toElement);
  }
  else if (evt.relatedTarget) {
    return !containsDOM(element, evt.relatedTarget);
  }
}
</script>
</head>
<body>
<div style="border: 1px solid green;"
     onmouseover="if (checkMouseEnter(this, event)) {
                    window.status = event.type;
                  }"
     onmouseout="if (checkMouseLeave(this, event)) {
                   window.status = event.type;
                 }">
 Kibology for all.
 <br>
 <a href="http://www.kibo.com/">Visit GOD</a>
 <br>
 All for Kibology.
</div>
<hr>
<div style="border: 1px solid green;"
     onmouseout="if (checkMouseLeave(this, event)) {
                   this.style.visibility = 'hidden';
                 }">
 This div element with the green border gets hidden when the mouse 
leaves the div.
<div style="border: 1px solid blue;">
 Child div with blue border.
</div>
 Kibology for all.
</div>
<hr>
<div style="border: 1px solid green;"
     onmouseover="if (checkMouseEnter(this, event)) {
                    this.style.visibility = 'hidden';
                  }">
This div element with the green border gets hidden when the mouse enters
the div.
<div style="border: 1px solid blue;">
 Child div with blue border.
</div>
 Kibology for all.
</div>
</body>
</html>
NN4 doesn't have this problem as it uses event capturing not bubbling 
so unless you explictly request it the child events do not show up at 
the parent element.
Note that IE5.5/6 provides two new event handlers onmouseenter and 
onmouseleave to faciliate scripting this situation.