有没有更好的方法来悬停卡?

时间:2012-12-23 01:24:10

标签: javascript jquery hover

在我的网站上,我将鼠标悬停在用户个人资料图片上。我有两个问题。

  1. 我遇到的第一个问题是,当您将鼠标移到或移出个人资料图片时,它在显示和隐藏方面效果不佳。当您将鼠标快速移动到图片上时(就像您只是将鼠标移动到页面上一样)大约一秒后它仍会弹出。我不明白为什么虽然它正在这样做。 只有在1000毫秒的悬停时才会弹出卡片。

  2. 我遇到的第二个问题是,如果你徘徊在一张照片上并且你移动到另一张照片(就像它正上方的照片),那么在另一张照片关闭之前它将无法工作直到你移动将鼠标移开图片,然后将其移回图片上。

  3. 我想知道是否有更好的方法来完成mouseenter和mouseleave事件,而不是我现在正在做的事情。

    hover card screenshot

    这是我的悬停卡JavaScript:

    var timeout, timeout2, hovercard_request;
    $('.profile-hovercard').live('mouseenter',function() {
    if(!$('#hovercard').hasClass('open')) {
        var id = $(this).attr('data-id'),
            pos = $(this).offset(),
            width = $(this).outerWidth(),
            miniprofile_url = $(this).parent().attr('href') + '/mini_profile';
        timeout = setTimeout(function() {
            //$('#hovercard').remove();
            if ($('#hovercard').length <= 0) {
                var hc = '<div id="hovercard" class="open"> \
                  <div class="hovercard-loading"><img src="/assets/img/ProgressIndicator.gif" /></div> \
                  </div>';
                $('body').append(hc);
                $('#hovercard').css({
                    'position': 'absolute',
                    'top': pos.top + "px",
                    'left': (pos.left + width + 11) + "px"
                });
            }
            else {
                $('#hovercard').css({
                    'position': 'absolute',
                    'top': pos.top + "px",
                    'left': (pos.left + width + 11) + "px"
                }).html('<div class="hovercard-loading"><img src="/assets/img/ProgressIndicator.gif" /></div>').show().addClass('open');
            }
            $.get(miniprofile_url, {}, function(data) {
                $('#hovercard').html('<div class="hovercard-inner"> \
                                      <div class="hovercard-pic"> \
                                         <a href="'+data.url+'"><img src="' + data.img_path + '" alt="' + data.name + '" /></a> \
                                      </div> \
                                     <div class="hovercard-details"> \
                                     <h3><a href="'+data.url+'">' + data.name + ( data.you == 1 ? ' <span style="font-weight:normal">(you)</span>' : '' ) + '</a> ' + ( data.is_online ? '<span class="online-user-icon m" title="'+data.name+' is online."></span>' : '') + '</h3> \
                                     <div class="hovercard-stats"> \
                                         <strong class="points">' + data.points + ' point' + (data.points == 1 ? '' : 's') + '</strong><br /> \
                                         <strong>' + data.questions + '</strong> question' + (data.questions == 1 ? '' : 's') + ' / <strong>' + data.answers + '</strong> answer' + (data.answers == 1 ? '' : 's') + '<!-- / <strong>' + data.comments + '</strong> comment' + (data.comments == 1 ? '' : 's') + '--><br /> \
                                         <span class="location">' + data.location + '</span> \
                                     </div> \
                                     </div> \
                                     <div class="clear"></div> \
                                     </div>');
                if(data.bio !== '') {
                    $('#hovercard').append('<div class="hovercard-bio">' + data.bio + '</div>');
                }
                else {
                    $('#hovercard').append('<div class="hovercard-bio"><em>This user does not have a bio.</em></div>');
                }
            },'json').fail(function() {
                $('#hovercard').html('<div class="hovercard-loading">The request has failed. Please try again later.</div>');
            }).error(function() {
                $('#hovercard').html('<div class="hovercard-loading">An error has occurred. Please try again later.</div>');
            });
        }, 1000);
    } // end if
    });
    $('.profile-hovercard').live('mouseleave',function() {
        clearTimeout(timeout);
        //hovercard_request.abort();
        timeout2 = setTimeout(function() {
           $('#hovercard').hide().removeClass('open');
        }, 400);
        $('#hovercard').hover(function() {
            clearTimeout(timeout2);
        },function() {
            timeout2 = setTimeout(function() {
                $('#hovercard').hide().removeClass('open');
            }, 300);
        });
    });
    

    当你将鼠标悬停在某人的照片上时,它旁边会弹出一个小框,显示他们的一些信息。在上面的代码中,我有所有超时,因为这是我可以让卡保持打开的唯一方法,所以有人可以在没有卡关闭的情况下将鼠标移动到卡上。

2 个答案:

答案 0 :(得分:2)

您可以尝试在clearTimeout(x);之前添加setTimeout。这应该确保计时器没有启动两次。

这段代码仍然可以使用一些重构; mouseenter处理程序很长,这使得它更难理解它的作用和调试。

var timeout, timeout2, hovercard_request;
$('.profile-hovercard').live('mouseenter', function() {
    if (!$('#hovercard').hasClass('open')) {
        var id = $(this).attr('data-id'),
            pos = $(this).offset(),
            width = $(this).outerWidth(),
            miniprofile_url = $(this).parent().attr('href') + '/mini_profile';

        clearTimeout(timeout);
        timeout = setTimeout(function() {
            //$('#hovercard').remove();
            if ($('#hovercard').length <= 0) {
                var hc = '<div id="hovercard" class="open"> \
              <div class="hovercard-loading"><img src="/assets/img/ProgressIndicator.gif" /></div> \
              </div>';
                $('body').append(hc);
                $('#hovercard').css({
                    'position': 'absolute',
                    'top': pos.top + "px",
                    'left': (pos.left + width + 11) + "px"
                });
            }
            else {
                $('#hovercard').css({
                    'position': 'absolute',
                    'top': pos.top + "px",
                    'left': (pos.left + width + 11) + "px"
                }).html('<div class="hovercard-loading"><img src="/assets/img/ProgressIndicator.gif" /></div>').show().addClass('open');
            }
            $.get(miniprofile_url, {}, function(data) {
                $('#hovercard').html('<div class="hovercard-inner"> \
                                  <div class="hovercard-pic"> \
                                     <a href="' + data.url + '"><img src="' + data.img_path + '" alt="' + data.name + '" /></a> \
                                  </div> \
                                 <div class="hovercard-details"> \
                                 <h3><a href="' + data.url + '">' + data.name + (data.you == 1 ? ' <span style="font-weight:normal">(you)</span>' : '') + '</a> ' + (data.is_online ? '<span class="online-user-icon m" title="' + data.name + ' is online."></span>' : '') + '</h3> \
                                 <div class="hovercard-stats"> \
                                     <strong class="points">' + data.points + ' point' + (data.points == 1 ? '' : 's') + '</strong><br /> \
                                     <strong>' + data.questions + '</strong> question' + (data.questions == 1 ? '' : 's') + ' / <strong>' + data.answers + '</strong> answer' + (data.answers == 1 ? '' : 's') + '<!-- / <strong>' + data.comments + '</strong> comment' + (data.comments == 1 ? '' : 's') + '--><br /> \
                                     <span class="location">' + data.location + '</span> \
                                 </div> \
                                 </div> \
                                 <div class="clear"></div> \
                                 </div>');
                if (data.bio !== '') {
                    $('#hovercard').append('<div class="hovercard-bio">' + data.bio + '</div>');
                }
                else {
                    $('#hovercard').append('<div class="hovercard-bio"><em>This user does not have a bio.</em></div>');
                }
            }, 'json').fail(function() {
                $('#hovercard').html('<div class="hovercard-loading">The request has failed. Please try again later.</div>');
            }).error(function() {
                $('#hovercard').html('<div class="hovercard-loading">An error has occurred. Please try again later.</div>');
            });
        }, 1000);
    } // end if
});
$('.profile-hovercard').live('mouseleave', function() {
    clearTimeout(timeout2);
    //hovercard_request.abort();
    timeout2 = setTimeout(function() {
        $('#hovercard').hide().removeClass('open');
    }, 400);
    $('#hovercard').hover(function() {
        clearTimeout(timeout2);
    }, function() {
        clearTimeout(timeout2);
        timeout2 = setTimeout(function() {
            $('#hovercard').hide().removeClass('open');
        }, 300);
    });
});

答案 1 :(得分:1)

这是你可以做到的一种方式:

var timeout;

$('.profile').hover(function() {
    pos = $(this).offset();

    timeout = setTimeout(function() {
        $('.hovercard').fadeIn().css({
            'top': pos.top - 20 + 'px',
            'left': pos.left - 20 + 'px'
        });
    }, 1000);

}, function() {
    clearTimeout(timeout);
});

$('.hovercard').mouseleave(function() {
    $('.hovercard').fadeOut();
});​

基本上,您为hovercard提供额外的填充,以便它也覆盖了个人资料图片。这意味着您可以使用mouseenter事件的个人资料图片和mouseleave事件的悬浮卡。

示例:http://jsfiddle.net/grc4/C8VTS/1/