SitePoint Sponsor

User Tag List

Results 1 to 13 of 13
  1. #1
    SitePoint Enthusiast
    Join Date
    Nov 2003
    Location
    Maryland
    Posts
    28
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    onmouseout being signaled w/o leaving the element

    I have a DIV that contains some anchors arranged vertically. On the DIV element I have an onmouseout event handler. If I move the mouse over one of the anchors, and then move it to another anchor (while remaining inside the DIV), the onmouseout event handler gets triggered even though the mouse never went outside the DIV. This happens in IE, Opera, and Mozilla.
    You can see this problem for yourself here:

    http://home.comcast.net/~delerious1/index4.html

    Does anyone know why this is happening?

  2. #2
    SitePoint Zealot tss68nl's Avatar
    Join Date
    Nov 2002
    Location
    Netherlands
    Posts
    165
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Because events bubble up by default. This is a handy way to catch onmouseovers / onmouseouts for a whole table at once for example. Say you need to make it highlight its rows, you can just catch all onmouseovers/onmouseouts at the table level, the only thing you need to do is get the source element of the event, and search it's containing TR object to make changes on. Saves you having 400+ onmouseover="..." onmouseout="..." things in your code.

    The easiest way to check wether you really went out of the div, is to get the event.toElement, and see if it resides inside the DIV using the divs ID, and the .contains() function.

    Code:
    oDiv = // some way to aquire your DIV here
    if (!oDiv.contains(event.toElement)) {
       // mouseout really went out of the DIV
    }
    Similar can be done for the onmouseover event. Note that you can probably make the oDiv object a fixed reference in your code since it's a waste having to find it each and every mouseover/mouseout.

  3. #3
    I'll take mine raw silver trophy MikeFoster's Avatar
    Join Date
    Dec 2002
    Location
    Alabama, USA
    Posts
    2,560
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    tss68nl is right, but be aware that contains() and toElement are non-standard and not supported by Mozilla. I experimented with this a little:
    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
    <style type='text/css'>
    #menu {
      width:50%;
      color:#000; background:#ccc;
    }
    a {
      display:block; width:50%;
      margin:1em;
      color:#000; background:#ccf;
    }
    </style>
    <script type='text/javascript'>
    var oMenu, uCount1=0, uCount2=0;
    window.onload = function() {
      if (document.getElementById) oMenu = document.getElementById('menu');
      else if (document.all) oMenu = document.all['menu'];
      if (oMenu) {
        oMenu.onmouseout = menuOnMouseout;
      }
    }
    function menuOnMouseout(evnt)
    {
      var s='', e = evnt || window.event;
      if (e) {
        var oTo = e.relatedTarget || e.toElement;
        // Determine if the mouse moved to an element contained by the div.
        while (oTo && oTo.id != 'menu') {
          oTo = oTo.parentNode || oTo.parentElement;
        }
        if (oTo) {
          s = 'mouse is still IN div, count1: ' + ++uCount1;
        }
        else {
          s = 'mouse moved OUT of div, count2: ' + ++uCount2;
        }
        window.status = s;
      }
    }
    </script>
    </head>
    <body>
    
    <div id='menu'>
      <a href=''>link</a>
      <a href=''>link</a>
      <a href=''>link</a>
      <a href=''>link</a>
    </div>
    
    </body>
    </html>
    Last edited by MikeFoster; Dec 11, 2003 at 10:33.

  4. #4
    SitePoint Enthusiast
    Join Date
    Nov 2003
    Location
    Maryland
    Posts
    28
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hmm, how about using window.event.cancelBubble=true or event.stopPropagation()?

  5. #5
    I'll take mine raw silver trophy MikeFoster's Avatar
    Join Date
    Dec 2002
    Location
    Alabama, USA
    Posts
    2,560
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hmm, how about using window.event.cancelBubble=true or event.stopPropagation()?
    You would have to add an event listener on each A element, and in that listener cancel bubbling. However the DIV also receives a mouseout event when the mouse moves from the DIV background onto an element in the DIV. So the DIV's mouseout listener must decide if the mouse moved onto one of its child elements or onto an element outside the DIV.

  6. #6
    SitePoint Zealot tss68nl's Avatar
    Join Date
    Nov 2002
    Location
    Netherlands
    Posts
    165
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well I suppose what you could do is just check the element that triggered the event, get it's tagname, and just rule A - tags and what not out?

    It's a poor excuse for a sturdy all catching solution, but it can be tailor made to your specific situation and work fine I think?

    That would be event.srcElement.tagName you'd have to check on. Set it up and print the contents of that tagName to a div on each event, just so you can see when and what gets triggered.

  7. #7
    I'll take mine raw silver trophy MikeFoster's Avatar
    Join Date
    Dec 2002
    Location
    Alabama, USA
    Posts
    2,560
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    go for it

  8. #8
    SitePoint Member
    Join Date
    Oct 2003
    Location
    USA
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I found this link on another forum. Maybe it will help. http://www.dyn-web.com/test/mouseout.html . The code is very short and "general".

  9. #9
    I'll take mine raw silver trophy MikeFoster's Avatar
    Join Date
    Dec 2002
    Location
    Alabama, USA
    Posts
    2,560
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the link uneverno but... (since we're comparing that page to my example)... that code is no "shorter" than mine just because I've used more whitespace, curly braces, and comments. That code uses the exact same technique as my code. That page presents some bad habits: (1) inline CSS; (2) inline event handlers. We should be moving away from these habits in order to separate our js, css, and html as much as possible.

  10. #10
    SitePoint Enthusiast
    Join Date
    Nov 2003
    Location
    Maryland
    Posts
    28
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the replies, guys. I'll try your suggestions out.

  11. #11
    SitePoint Enthusiast
    Join Date
    Nov 2003
    Location
    Maryland
    Posts
    28
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    OK I've almost got this working... it works in Mozilla and Opera, but not in IE. Here's an example of the latest problem:
    http://home.comcast.net/~delerious1/index4.html

    If you look at that page in IE, you will notice that the submenu disappears when you move the mouse from one link to another. This is because when you move the mouse off of a link, an onmouseout event is generated with relatedTarget/toElement=<DIV that contains the content>. In the HTML, the DIV that contains the content is not a child of the submenu DIV, so the submenu disappears.

    Also notice that I have specified a height style for the submenu Anchors. If I remove the height style, then moving the mouse from one link to another does not generate an onmouseout event with relatedTarget/toElement=<DIV that contains the content>, and the problem does not occur. But my real page is not quite the same as that example page, and I need to specify the height style.

    So does anyone know how to get around this IE problem?
    Last edited by delerious; Dec 12, 2003 at 01:10.

  12. #12
    SitePoint Member
    Join Date
    Oct 2003
    Location
    USA
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you put a background-color on the submenu that won't happen. I remember reading something somewhere about events "falling through" to content underneath in IE.

  13. #13
    SitePoint Enthusiast
    Join Date
    Nov 2003
    Location
    Maryland
    Posts
    28
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hey I just found this microsoft article which seems to describe the same problem I am experiencing:
    http://support.microsoft.com/default...NoWebContent=1

    When I use that filter:alpha(opacity=0) style though, it makes the whole submenu invisible (although you can still click on the links)! Also, the filter style is not supported by Mozilla or IE, so this does not seem like a solution for me. I guess I could try the transparent gif solution, but that seems like such a kludge!


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •