0

I have tried the following two methods to display hidden contents that comes with each div that has the class name avatar.

<div class="avatar"><a><img src="avatar.png" width="36" height="36"><div class="profile">Users Profile with Link</div></a></div>

The first one uses hover and works perfectly when I have multiple avatar elements on the page.

Unfortunately the tool tip has a clickable link built in and hover does not allow me to click on the link.

    $('.avatar a').hover(function () {
        $(this).contents('div:last-child').css({
            display : 'inline'
        });
    }, function () {
        $(this).contents('div:last-child').css({
            display : 'none'
        });
    });

Unfortunately the tool tip has a clickable link built in and hover does not allow me to click the link.

I than pieced together coding that I found here that uses mouseenter and mouseleave. This one also works and it allows me to click the link.

    var hover = null;
    $('.avatar a').bind('mouseleave', function() {
        var $this = $(this).contents('div:last-child');
        hover = setTimeout(function() {
            $this.fadeOut(400);
        }, 800);
    });

    $('.avatar a').bind('mouseenter', function() {
        $(this).contents('div:last-child').css({display:'block'});
        if (hover !== null) {
            clearTimeout(hover);
        }
    });

Unfortunately if you mouse over more than one of these avatars only the last one gets removed while others always remain.

My question is how do I use the second one which will fadeOut any active tool tips when I move on to another?

Am I missing something? Or doing this wrong altogether?

Tim
  • 403
  • 1
  • 6
  • 20

3 Answers3

1

The problem is in your timeout function.. Why are u even using it? http://jsfiddle.net/24MYq/9/ remove:

    if (hover !== null) {
    clearTimeout(hover);
}

isn't this what you need or do you need that delay? if you really need it, I will edit my post and give you some working delay.

E: For a delay either higher the number inside the fadeOut() or add a .delay(number) afterwards while number is an int value (500 -> half a second)

gulty
  • 1,068
  • 1
  • 8
  • 14
  • Yes it needs to remain as it keeps the current tool tip active as long as your mouse remains within this element. When I remove this as suggested it fades out and these elements have profile information including links. – Tim Feb 11 '13 at 17:44
  • I had a look at your jsFiddle example; that works perfectly. Let me rewrite what I have based on your example. Thanks – Tim Feb 11 '13 at 17:49
0

If you want them all to be removed when you mouse away, you can do so by changing var $this = $(this).contents('div:last-child') to var $this = $('.profile');

All tooltips will disappear at the same time, and the timeout will reset whenever you mouse over another avatar image, though.

Fedoranimus
  • 816
  • 6
  • 20
  • This works by keep them all active and then they fade out. Is there away to automatically fade them all out and only have one active? – Tim Feb 11 '13 at 17:47
0

If I understand correctly, I think what you want is to have a timeout on each tip. You can use .data to accomplish this by associating a timeout with each tip.

$('.avatar a').on('mouseleave', function() {
    var $tip = $(this).contents('div:last-child');
    $tip.data('hover', setTimeout(function() {
        $tip.fadeOut(400);
        $tip.removeData('hover');
    }, 800));
});

$('.avatar a').on('mouseenter', function() {
    var $tip = $(this).contents('div:last-child').show();
    var hover = $tip.data('hover');
    if (hover) {
        clearTimeout(hover);
        $tip.removeData('hover');
    }
});

Live demo on jsfiddle

Note: I also changed .bind() to .on() since .bind() is deprecated, and I changed it to use .show().

What was happening in your original code is that the timeout for the first tip was cleared when you hovered over the second tip because they all shared the same "hover" variable.

EDIT: In my haste I was incorrectly clearing the .data values. I should have been using .removeData(). I have fixed the code above.

Updated demo on jsfiddle

John S
  • 21,212
  • 8
  • 46
  • 56
  • This works just like what I was thinking. The tool tips show up on mouse over and remain open. If you mouse over the others they fade out and the active one always remains active. Thank very much John! – Tim Feb 11 '13 at 18:00
  • Just put it into my scripting and beautiful! Thanks again. – Tim Feb 11 '13 at 18:04
  • One more thing, I believe it is more efficient to use `$('.avatar').children('a')` than `$('.avatar a')` because the former finds all elements with the "avatar" class and then gets the children, while the latter finds all "a" tags and then looks for the class. (The selectors are parsed right to left.) – John S Feb 11 '13 at 18:07
  • I switched over to $('.avatar').children('a') to make it more affected as suggested. Though I do have another question - I will ask this separately as this has to do with an new problem I am noticed. – Tim Feb 25 '13 at 15:36
  • Adding new content through AJAX the above .on() mouseleave and mouseenter does not work with the dynamically loaded content. It does if I downgrade to use .live(), but I prefer to keep with the latest functions. Is there a replacement for .live()? – Tim Feb 25 '13 at 15:38
  • The replacement for `.live()` is to use `.on`, but you call it on the element that will receive the event, and then add an extra parameter that identifies the child elements to which the event will be delegated. Try this `$(document.body).on('mouseleave', '.avatar a', function() {...})`. If you can specify a more direct parent element than the body, you should. – John S Feb 25 '13 at 19:36
  • You know I did try that but did not have "document.body", adding that made a big difference and works. John - you are the man! Thanks once again. – Tim Feb 25 '13 at 19:45