jQuery悬停情况

时间:2012-06-07 16:15:42

标签: jquery jquery-hover

所以我有这段代码,它创建一个div来阻止一个复选标记的图像,然后向右滑动使它看起来像正在绘制复选标记。一切正常,除非我希望代码执行,好像用户暂停一段时间,即使用户只是暂停一瞬间。目前,当用户停止悬停时动画停止。谢谢大家!

$('li.activated').hover(function () {
    $('ul.actilist').prepend($('<div>&nbsp;</div>').addClass('slidebox'));
}, function () {
    $('ul.actilist').find('div.slidebox').remove();
});

$('li.activated').hover(function() {
    $('div.slidebox').animate({width: '-=17px', marginLeft: '+=14px'}, {duration: '800',easing: 'swing',queue: true});
}, function() {
    if( $('div.slidebox').width() < 17 ){
        $('div.slidebox').animate({width: '+=17px', marginLeft: '-=14px'}, {duration: '2000',easing: 'swing',queue: true});
    }
});

2 个答案:

答案 0 :(得分:0)

您可以使用setTimeout功能延迟mouseleave事件:

setTimeout(function() {
    $('div.slidebox').animate({width: '+=17px', marginLeft: '-=14px'}, {duration: '2000',easing: 'swing',queue: true});
}, 800);

但这并不能完全满足您的需求,因为如果用户将鼠标移出并急忙重新进入,则div将进一步缩小,然后在超时到期后再增长回其预期大小。 (反复执行此操作会导致div暂时缩小为空。)为了防止这种情况,您需要防止在“取消mouseleave”的情况下触发悬停事件。这需要更多代码:

var hovered = false;

$('li.activated').hover(function() {
    if(hovered) return;
    hovered = true;
    $('div.slidebox').animate({width: '-=17px', marginLeft: '+=14px'}, {duration: '800',easing: 'swing',queue: true});
}, function() {
    var element = this;
    setTimeout(function() {
        if($(element).is(':hover') || !hovered) return;
        hovered = false;
        $('div.slidebox').animate({width: '+=17px', marginLeft: '-=14px'}, {duration: '2000',easing: 'swing',queue: true});
    }, 800);
});​

jsFiddle:http://jsfiddle.net/uUjhJ/2/

这主要是有效的,但是通过一些勤奋的鼠标挥动,可以使动画“破解”并开始像风箱一样抽水(直到它通过动画队列)。这是通过在播放mouseleave动画时将鼠标移回来开始的,而我能够找到修复它的唯一方法是将“queue”选项设置为false并将动画值更改为固定值(而不是比使用+ =和 - =)的相对值:

var hovered = false;

$('li.activated').hover(function() {
    if(hovered) return;
    hovered = true;
    $('div.slidebox').animate({width: '83px', marginLeft: '14px'}, {duration: '800',easing: 'swing',queue: false});
}, function() {
    var element = this;
    setTimeout(function() {
        if($(element).is(':hover') || !hovered) return;
        hovered = false;
        $('div.slidebox').animate({width: '100px', marginLeft: '0px'}, {duration: '2000',easing: 'swing',queue: false});
    }, 800);
});​

jsFiddle:http://jsfiddle.net/uUjhJ/3/

理论上应该可以通过在animate的调用中仔细跟踪状态和使用回调来使原始方法正常工作,但它非常挑剔并且我无法使其工作

编辑:啊,错过了你还想在悬停事件中添加/删除div。这样做了:

var hovered = false;

$('li.activated').hover(function() {
    if(hovered) return;
    hovered = true;
    if(!$('div.slidebox').length)
        $('ul.actilist').prepend($('<div>&nbsp;</div>').addClass('slidebox'));
    $('div.slidebox').animate({width: '83px', marginLeft: '14px'}, {duration: '800',easing: 'swing',queue: false});
}, function() {
    var element = this;
    setTimeout(function() {
        if($(element).is(':hover') || !hovered) return;
        hovered = false;
        $('div.slidebox').animate({width: '100px', marginLeft: '0px'}, {duration: '2000',easing: 'swing',queue: false,complete: function() {
            if($(element).is(':hover')) return;
            $('ul.actilist').find('div.slidebox').remove();
        }});
    }, 800);
});​

请注意,在“完整”回调中删除了该元素,以确保在动画之后而不是之前删除该元素,并且添加代码和删除代码都会仔细检查它们是否与任何内容冲突(双 - 在重新显示时添加或删除。)

jsFiddle:http://jsfiddle.net/uUjhJ/4/

答案 1 :(得分:-1)

我不太熟悉hover()函数,但该代码应该对动画进行排队(未经过测试):

$('li.activated').mouseenter(function() {
    $('div.slidebox').animate({width: '-=17px', marginLeft: '+=14px'}, {duration: '800',easing: 'swing',queue: true});
}).mouseleave(function() {
    if( $('div.slidebox').width() < 17 ){
        $('div.slidebox').animate({width: '+=17px', marginLeft: '-=14px'}, {duration: '2000',easing: 'swing',queue: true});
    }
});