-3

所以我有这段代码,它创建一个 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});
    }
});
4

2 回答 2

0

您可以使用该setTimeout函数来延迟 mouseleave 事件:

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

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

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 动画播放时将鼠标移回开始的,我能够找到修复它的唯一方法是将“队列”选项设置为 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/

于 2012-06-08T06:44:40.800 回答
-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});
    }
});
于 2012-06-07T16:22:18.447 回答