Why is it flickering?

Author: Dave Cassel  |  Category: Software Development

A friend of mine is learning JavaScript and jQuery and I recently helped her out with a problem she was having. She wanted to mouse over an image and have another <div/> appear, giving information about the image. Okay, nothing real strange there. But in her initial implementation she would mouse over the trigger image, the popup would appear, but then the popup would flicker, disappearing and reappearing repeatedly. I took what she started with and simplified it down to this to illustrate the problem:

<html>
  <head>
    <link rel="stylesheet" type="text/css" href="styles.css">
    <style type="text/css">
      #trigger {
        background-color: blue;
        display: block;
        height: 50px;
        width: 50px;
      }

      #popup {
        background-color: yellow;
        display: none;
        height: 200px;
        left: 25px;
        position: absolute;
        top: 25px;
        width: 100px;
      }
    </style>
    <script src="http://code.jquery.com/jquery-latest.js"></script>
    <script>
      $(document).ready(function(){
        $('#trigger').mouseover(function(){
          $('#popup').show('fast');
        });

        $('#trigger').mouseleave(function(){
          $('#popup').hide('fast');
        });
      });
    </script>
  </head>
  <body>
    <div id="trigger"></div>
    <div id="popup">Here is a bunch of text that will appear in the window
      that pops up. Lorem Ipsum and all that jazz.</div>
  </body>
</html>

If you view the page and point to the blue square, a yellow square with text pops up. Now move the mouse from the blue area to the yellow. As long as you’re in the overlap, the yellow area will repeatedly disappear and reappear.

What we wanted was that when you mouse over the blue, the popup would appear, and it would stay there until the mouse was over neither the blue trigger area nor the yellow popup. So that meant we needed to work with jQuery’s mouseleave event to hide the popup when leaving the target area. Here’s where it got tricky.

The area in red in the image to the left reflects the overlap of the two divs. Let’s think about what happens when we move the mouse from the blue trigger area to the red overlap. When the mouse crosses the line into the red, that triggers a mouseleave event from the trigger area. When that happens, we hide the popup. With the popup gone, the mouse is suddenly back in the blue div again. Mouseenter! That shows the popup again. Mouseleave! And so on.

So, what’s the solution? It was pretty straightforward in this case, once we understood what was happening. The real problem is that the trigger and popup divs are separate. In fact, the popup div should be a part of the trigger div, and then suddenly everything is easy. Why does that make a difference?

Take a look at the screenshot to the right. Here, the red area outlines the boundaries of the trigger div. Because the popup is now a child of the trigger, the mouse can roam around the yellow area without having left the trigger div, so we keep the popup showing.

The difference in the code is very simple; we just moved one div inside another, like so:

  <body>
    <div id="trigger">
      <div id="popup">Here is a bunch of text that will appear in the window
        that pops up. Lorem Ipsum and all that jazz.</div>
    </div>
 </body>

Of course, that led to some changes in the positioning of the popup, but that’s just a matter of working out new values for your CSS.

Moral of the story: when you want a popup, make it part of the trigger. That will let you have one region for the mouse to roam around in, making the event management nice and easy!

Tags: ,

5 Responses to “Why is it flickering?”

  1. Jeremy Says:

    You my man, are a legend. I’ve been trying to figure this out for hours! I’m only pretty new to jQuery and I thought it was an issue with my code, apparently not. I moved the popup inside the trigger and boom, it worked!

  2. Rytis Says:

    Thanx

  3. diana Says:

    The problem I’m having is that I have one large image that has many rollovers with pop up boxes. With the solution here, if I rollover any of my divs, all pop ups pop up at the same time because they are on the same trigger. I can’t get individual popups depending on the location. Please advise.

  4. Dave Cassel Says:

    Hi Diana. Offhand it sounds like you’re using the same id on each of the trigger divs. If you aren’t already, try giving each one a unique id. In that case, I think you’d need to repeat some of the JS code. Another idea to try (I haven’t tested this):

    <div class="trigger">
    <div class="popup">Here is a bunch of text that will appear in the window
    that pops up. Lorem Ipsum and all that jazz.</div>
    </div>

    <script>
    $(document).ready(function(){
    $('.trigger').mouseover(function(){
    $(this).find('.popup').show('fast');
    });

    $('.trigger').mouseleave(function(){
    $(this).find('.popup').hide('fast');
    });
    });
    </script>

    The idea is to specify that only popup to show/hide should be the one under the trigger that got hit.

  5. Angie Says:

    I think you triggered this problem, not your imaginary female friend

Leave a Reply