1

在这个jsFiddle 中,我有一个简单的自定义上滑/下滑动画(代码的所有功劳归功于 ebram tharwat)。问题是……你猜对了:双击。如果您在 500 毫秒(动画完成所需的时间)内多次单击向上/向下按钮,它会搞砸一切。我试过 stop(true); 和 preventDefault 但无济于事。任何帮助总是真正感激。

示例代码:

$("#upBtn").on('click', function () {
    // slide all optionMenu_* up by 80px
    var maxUp = ($('div.optionMenu').length - 3) * 90;
    if (parseInt($('.sliderContainerInside').css('top')) - 10 > -maxUp) {
        $('.sliderContainerInside').animate({
            top: parseInt($('.sliderContainerInside').css('top')) - 90 + 'px'
        }, 500);
    }
});

谢谢。

佩德罗

4

6 回答 6

1

检查是否元素.is(':animated')并返回false;如果您希望动画在另一个被触发之前完成

if($('.sliderContainerInside').is(':animated')){
    return false;   
}

同样对于您可以使用的顶级属性'+=90px',而'-=90px'不是

parseInt($('.sliderContainerInside').css('top')) - 90 + 'px'

小提琴

于 2013-04-09T13:52:22.723 回答
1

我认为这里最有用的方法是stop在新点击时播放动画,并且只听最后一次点击。此外,您需要根据动画元素的当前位置以外的其他内容计算您的位置,因为当您在动画中间单击时,这会让您感到厌烦。

类似于全局变量的东西:

var target = 10;

$("#upBtn").on('click', function () {
    // slide all optionMenu_* up by 80px
    var maxUp = ($('div.optionMenu').length - 3) * 90;
    if (target > maxUp * -1) {
        target -= 90;
        $('.sliderContainerInside').stop().animate({top: target }, 500);
    }
});

演示

于 2013-04-09T13:54:34.797 回答
1

如果可以使用按钮,请<button id="upBtn">Up</button>尝试以下jsfiddle

if (parseInt($('.sliderContainerInside').css('top')) - 10 > -maxUp) {
        $("#upBtn").attr('disabled', 'disabled');

并在动画完成后删除 disabled 属性

$('.sliderContainerInside').animate({
            top: parseInt($('.sliderContainerInside').css('top')) - 90 + 'px'
        }, 500,function(){$("#upBtn").removeAttr('disabled');});
于 2013-04-09T13:55:59.710 回答
1

这是一个有效的更新演示

正如我在前面的评论中提到的,主要问题是您正在根据动画元素本身的当前位置确定动画的新位置。这意味着如果你在动画中间开始一个新的动画,你的偏移量会变得很不稳定。

解决方案是预先计算所有偏移量,这样无论当前状态如何,您都可以始终知道正确的动画偏移量。您可以在上面发布的 jsfiddle 中看到这一点,但这里是供参考的代码:

var $sliderInside = $('.sliderContainerInside'),
    $items = $('.optionMenu'),
    currentItem = 0,
    maxItem = $items.length - 3,
    itemOffsets = $items.map(function() {
        return $(this).position().top * -1 + 10 + 'px';
    }).get();

$("#upBtn").on('click', function () {
    if (currentItem >= maxItem) return;
    currentItem++;
    $sliderInside.stop().animate({
        top: itemOffsets[currentItem]
    }, 500);
});

$("#downBtn").on('click', function () {
    if (currentItem <= 0) return;
    currentItem--;
    $sliderInside.stop().animate({
        top: itemOffsets[currentItem]
    }, 500);
});
于 2013-04-09T14:04:05.327 回答
1

这是我的做法:

var place = 0;
var position = 10;
var limit = parseInt($('div.optionMenu').length) - 3;

$("#upBtn").click(function () {
    // slide all optionMenu_* up by 80px
    if(place > 0) {
        place--;
    }
    animate();
});

$("#downBtn").click(function () {
    // slide all optionMenu_* up by -80px
    if(place < limit) {
        place++;
    }
    animate();
});

function animate() {
    position = 10 - (place*90);
    $('.sliderContainerInside').stop().animate({
        top: position + 'px'
    }, 500);
}

记住按钮被点击了多少次,并直接动画到正确的点。增加了不重复相同代码两次的好处。

jsFiddle

于 2013-04-09T14:07:20.830 回答
0

queue选项jQuery.animate()不能解决您的问题吗?

于 2013-04-09T13:44:30.010 回答