SitePoint Sponsor

User Tag List

Results 1 to 7 of 7
  1. #1
    Barefoot on the Moon! silver trophy Force Flow's Avatar
    Join Date
    Jul 2003
    Location
    Northeastern USA
    Posts
    4,606
    Mentioned
    56 Post(s)
    Tagged
    1 Thread(s)

    jQuery tooltip issue

    I built a tooltip, but the hover effect isn't quite working properly.

    Basically, hover on the "?" icon, and a tooltip appears.

    • If the mouse leaves the "?", the tooltip fades out after a moment.
    • If the mouse slides over to hover on the tooltip itself, the tooltip is prevented from fading out (until the mouse leaves the tooltip, or until the tooltip is clicked).
    • Only one tooltip at a time can appear (if the mouse slides from one "?" to another, then the old tooltip fades out).


    The problem is that when the mouse slides from the "?" to the tooltip, the tooltip blinks. I've been trying to fix it, and I suspect it has something to do with the jQuery selector I'm using for determining when to hide the tooltip. It's not that the delay time is too short either. I can set it for 2000, and the tooltip would still blink.

    Here's the code:

    Code HTML4Strict:
    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>tooltip test</title>
    <style type="text/css">
    /* start reset */
    body,div,span,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,button,p,blockquote,table,th,td {
        margin: 0px;
        padding: 0px;
    }
    body {
        color: black;
        font-family: Verdana,Geneva,Arial,Helvetica,sans-serif;
        font-size: 100.01%;
    }
    a img { border: none; }
    /* end reset */
     
    /* start form styling */
    form {
        width: 600px;
        margin:0 auto;
    }
    form fieldset {
        position: relative;
        margin: 20px 0px 20px 0px;
        padding: 0px 12px 0px 12px;
        background-color: #ebeef3;
        border: 2px solid #4f53bc;
        -moz-border-radius: 5px;
        -webkit-border-radius: 5px;
        border-radius: 5px;
    }
    form .container {margin: 12px 12px 18px 30px;}
    form .question {padding: 14px 0px 16px 0px;}
     
    form .question label {
        margin-right: 8px;
        margin-bottom: 6px;
        color: #303030;
        font-weight: bold;
    }
    /* end form styling */
     
    /* start tooltip */
    a.tooltip img {
        position: relative;
        top: .3em;
    }
     
    a.tooltip {
        cursor: help;
        margin: 0px 12px 0px 12px;
        font-size: 99.9%; /* IE fix for hover tooltip */
    }
     
    a.tooltip,a.tooltip span.tt,a.tooltip span.p {text-decoration: none;}
     
    a.tooltip span.tt {
        display: none;
        position: absolute;
        z-index: 25;
        font-size: .7em;
        color: #666;
        border: 1px #d4d5aa solid;
        border-right-color: #b8b58f;
        border-bottom-color: #b8b58f;
        background-color: #FFFBC6;
        padding: 5px 8px 0px 8px;
        margin: -10px 0px 0px 25px;
        max-width: 225px;
        min-width: 150px;
        -moz-border-radius: 4px;
        -webkit-border-radius: 4px;
        border-radius: 4px;
        -moz-box-shadow: 3px 3px 5px #BCBCBC;
        -webkit-box-shadow: 3px 3px 5px #BCBCBC;
        box-shadow: 3px 3px 5px #BCBCBC;
    }
     
    a.tooltip span.tt span.p:first-child {font-weight: bold;}
    a:hover.tooltip_hover span.tt {display: inline;}
     
    a.tooltip span.tt span.p {
        display: block;
        margin: .2em 0 .8em 0;
    }
     
    /* end tooltip */
     
    </style>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
    <script type="text/javascript">
        $().ready(function(){
     
            $('fieldset a.tooltip').removeClass('tooltip_hover'); //remove CSS hover fallback
     
            $('fieldset a.tooltip, fieldset a.tooltip span.tt').hover(
                function(){
                    var tooltip = $(this).find('span.tt');
     
                    hide_tooltip($('fieldset a.tooltip span.tt').filter(':visible').not(tooltip)); //hide all tooltips but the current one - PROBLEM IS HERE?
     
                    $(tooltip).stop(true,true).animate({opacity:'show'},{queue:false, duration:100}); //show tooltip
                },
                function(){
                    var tooltip = $(this).find('span.tt');
                    $(tooltip).delay(600).fadeOut(300); //hide the tooltip
                }
            );
     
            $('fieldset a.tooltip span.tt').click(function(){
                hide_tooltip(this); //hide tooltip if it is clicked
            });
     
            function hide_tooltip(selection){
                $(selection).stop(true,true).animate({opacity:'hide'},{queue:false, duration:100});
            }
     
        });
    </script>
    </head>
    <body>
        <form>
            <fieldset>
                <div class="container">
     
                    <div class="question">
                        <label>Label Me This</label>
                        <a href="javascript:void(0);" class="tooltip tooltip_hover"><img src="http://img52.imageshack.us/img52/4199/icontooltip.png" class="pngfix" alt="" /><span class="tt"><span class="p">Title 1</span><span class="p">Blah blah blah yadda yadda yadda blah blah blah so on</span><span class="p">For example, blah blah blah yodel he hi ho</span></span></a>
                    </div>
     
                    <div class="question">
                        <label>Label Me That</label>
                        <a href="javascript:void(0);" class="tooltip tooltip_hover"><img src="http://img52.imageshack.us/img52/4199/icontooltip.png" class="pngfix" alt="" /><span class="tt"><span class="p">Title 2</span><span class="p">Blah blah blah yadda yadda yadda blah blah blah so on</span><span class="p">For example, blah blah blah yodel he hi ho</span></span></a>
                    </div>
     
                    <div class="question">
                        <label>Label Me Too</label>
                        <a href="javascript:void(0);" class="tooltip tooltip_hover"><img src="http://img52.imageshack.us/img52/4199/icontooltip.png" class="pngfix" alt="" /><span class="tt"><span class="p">Title Three</span><span class="p">Blah blah blah yadda yadda yadda blah blah blah so on</span><span class="p">For example, blah blah blah yodel he hi ho</span></span></a>
                    </div>
     
                </div>
            </fieldset>
        </form>
    </body>
    </html>
    Visit The Blog | Follow On Twitter
    301tool 1.1.5 - URL redirector & shortener (PHP/MySQL)
    Can be hosted on and utilize your own domain

  2. #2
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,700
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    When removing the tooltip, do it after a delay of half a second using setTimeout

    That way, when the mouse is moved to a section that results in the same tooltip being shown, you can remove the setTimeout timer that was previously there.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  3. #3
    Barefoot on the Moon! silver trophy Force Flow's Avatar
    Join Date
    Jul 2003
    Location
    Northeastern USA
    Posts
    4,606
    Mentioned
    56 Post(s)
    Tagged
    1 Thread(s)
    I'm not quite sure what you're describing. How would I remove the setTimeout?

    Code JavaScript:
        $().ready(function(){
     
            $('fieldset a.tooltip').removeClass('tooltip_hover'); //remove CSS hover fallback
     
            $('fieldset a.tooltip, fieldset a.tooltip span.tt').hover(
                function(){
                    var tooltip = $(this).find('span.tt');
     
                    setTimeout(function(){
                        hide_tooltip($('fieldset a.tooltip span.tt').filter(':visible').not(tooltip));
                    },500);//hide all tooltips but the current one - PROBLEM IS HERE?
     
     
                    $(tooltip).stop(true,true).animate({opacity:'show'},{queue:false, duration:100}); //show tooltip
                },
                function(){
                    var tooltip = $(this).find('span.tt');
                    $(tooltip).delay(600).fadeOut(300); //hide the tooltip
                }
            );
     
            $('fieldset a.tooltip span.tt').click(function(){
                hide_tooltip(this); //hide tooltip if it is clicked
            });
     
            function hide_tooltip(selection){
                $(selection).stop(true,true).animate({opacity:'hide'},{queue:false, duration:100});
            }
     
        });
    Visit The Blog | Follow On Twitter
    301tool 1.1.5 - URL redirector & shortener (PHP/MySQL)
    Can be hosted on and utilize your own domain

  4. #4
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,700
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by Force Flow View Post
    I'm not quite sure what you're describing. How would I remove the setTimeout?
    By using clearTimeout
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  5. #5
    Barefoot on the Moon! silver trophy Force Flow's Avatar
    Join Date
    Jul 2003
    Location
    Northeastern USA
    Posts
    4,606
    Mentioned
    56 Post(s)
    Tagged
    1 Thread(s)
    It works...but then another problem came up. Now more than one tooltip can show up at a time and they start overlapping (when moving the mouse from icon to icon). I even lowered the timeout from 500 down to 100, but multiple tooltips can still display at the same time.

    Code JavaScript:
        $().ready(function(){
     
            $('fieldset a.tooltip').removeClass('tooltip_hover'); //remove CSS hover fallback
     
            $('fieldset a.tooltip, fieldset a.tooltip span.tt').hover(
                function(){
                    var tooltip = $(this).find('span.tt');
     
                    var toID = setTimeout(function(){
                        hide_tooltip($('fieldset a.tooltip span.tt').filter(':visible').not(tooltip));
                    },100);//hide all tooltips but the current one - PROBLEM IS HERE?
     
     
                    $(tooltip).stop(true,true).animate({opacity:'show'},{queue:false, duration:100}); //show tooltip
                    clearTimeout(toID);
     
                },
                function(){
                    var tooltip = $(this).find('span.tt');
                    $(tooltip).delay(600).fadeOut(300); //hide the tooltip
                }
            );
     
            $('fieldset a.tooltip span.tt').click(function(){
                hide_tooltip(this); //hide tooltip if it is clicked
            });
     
            function hide_tooltip(selection){
                $(selection).stop(true,true).animate({opacity:'hide'},{queue:false, duration:100});
            }
     
        });

    [edit]: I lowered the timeout to 10, then 1, then 0, but it still operated the same way--multiple tooltips could be present at the same time.
    Visit The Blog | Follow On Twitter
    301tool 1.1.5 - URL redirector & shortener (PHP/MySQL)
    Can be hosted on and utilize your own domain

  6. #6
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,700
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by Force Flow View Post
    It works...but then another problem came up. Now more than one tooltip can show up at a time and they start overlapping
    Instead of storing the reference to the setInterval as a global variable, you can use jQuery's data method to store the info in relation to the link or the tooltip (whichever is easier to access)

    That way, you can have multiple timers set up and can deal with them individually on an as-needed basis
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  7. #7
    Barefoot on the Moon! silver trophy Force Flow's Avatar
    Join Date
    Jul 2003
    Location
    Northeastern USA
    Posts
    4,606
    Mentioned
    56 Post(s)
    Tagged
    1 Thread(s)
    Since that sounded like it was over-complicating things more than necessary, I went back a few steps and ended up removing the additional selector I had for the hover function. Since I added that in before I completely fixed a queuing buildup issue I had earlier, it seems to have done the trick.

    Code JavaScript:
        $().ready(function(){
     
            $('fieldset a.tooltip').removeClass('tooltip_hover'); //remove CSS hover fallback
     
            $('fieldset a.tooltip').hover(
                function(){
                    var tooltip = $(this).find('span.tt');
     
                    hide_tooltip($('fieldset a.tooltip span.tt').not(tooltip).filter(':visible'));//hide all tooltips but the current one
     
                    $(tooltip).stop(true,true).animate({opacity:'show'},{queue:false, duration:100}); //show tooltip
     
                },
                function(){
                    var tooltip = $(this).find('span.tt');
                    $(tooltip).delay(600).fadeOut(300).css('opacity',''); //hide the tooltip
                }
            );
     
            $('fieldset a.tooltip span.tt').click(function(){
                hide_tooltip(this); //hide tooltip if it is clicked
            });
     
            function hide_tooltip(selection){
                $(selection).stop(true,true).animate({opacity:'hide'},{queue:false, duration:100});
            }
     
        });
    Visit The Blog | Follow On Twitter
    301tool 1.1.5 - URL redirector & shortener (PHP/MySQL)
    Can be hosted on and utilize your own domain


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
  •