转盘的动画队列错误

An animation queue bug of carousel

本文关键字:队列 错误 动画      更新时间:2023-09-26

我正在写一个简单的旋转木马案例,但它有一个动画问题。

当您快速单击"上一步"或"下一步"按钮时,列表项目也会快速显示。

如何修复?

代码在这里:

html:

<div id="carousel" class="carousel">
    <div class="pagination">
        <a href="#" class="prev">prev</a>
        <a href="#" class="next">next</a>
    </div>
    <div class="play">
        <!-- initialize play number -->
    </div>
    <div class="pic">
        <ul>
            <li><a href="#">1</a></li>
            <li><a href="#">2</a></li>
            <li><a href="#">3</a></li>
            <li><a href="#">4</a></li>
            <li><a href="#">5</a></li>
            <li><a href="#">6</a></li>
        </ul>
    </div>
</div>

javascript代码:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js "></script>
<script type="text/javascript">
    $(function(){
        var containner=$('#carousel');
        var pagination=containner.find('.pagination');
        var play=containner.find('.play');
        var picList=containner.find('.pic ul li');
        var prev=pagination.find('.prev');
        var next=pagination.find('.next');
        var pageNum=0;
        var defaultAnimateDelay={
            show:800,
            hide:100
        };
        // initialize play number
        (function(picListLength){
            var playHtml='';
            for(var i=0; i<picListLength; i++){
                playHtml+='<a href="#" data-number="'+i+'">'+(i+1)+'</a>';
            }
            play.html(playHtml);
        })(picList.length);
        // 
        function Carousel(pageNumber){
            picList.eq(pageNumber)
            .stop(false,false)
            .animate({
                opacity:'show'
            },defaultAnimateDelay.show).siblings()
            .stop(false,false).animate({
                opacity:'hide'
            },defaultAnimateDelay.hide);
            // add Current class to current play number
            play.find('a')
            .eq(pageNumber)
            .addClass('current')
            .siblings('').removeClass('current');
        }
        // click prev event
        prev.on('click',function(e){
            e.preventDefault();
            if(pageNum===0){
                pageNum=(picList.length-1);
            }else {
                pageNum--;
            }
            Carousel(pageNum);
        });
        // click next event
        next.on('click',function(e){
            e.preventDefault();
            if(pageNum===(picList.length-1)){
                pageNum=0;
            }else{
                pageNum++;
            }
            Carousel(pageNum);
        });
        //  play number 
        play.on('click','a',function(e){
            e.preventDefault();
            pageNum=Number($(this).attr('data-number'));
            Carousel(pageNum);
        });
    });
</script>

Bootstrap carousel js运行良好,但它没有使用jquery停止函数。太神了

根据您的代码,一切都会立即发生。没有回调,因此不需要等待动画结束。您的代码可以重新组织,使其可读性更强,更易于重构。以下是我想尝试的:

function show(pageNumber){
    return picList.eq(pageNumber)
    .animate({
        opacity:'show'
    },defaultAnimateDelay.show).promise();
}
function hide(pageNumber){
    return picList.eq(pageNumber)
    .stop(false,true)
    .siblings()
    .stop(false,false)
    .animate({
        opacity:'hide'
    },defaultAnimateDelay.hide).promise();
}
function Carousel(pageNumber){
    var promise = hide(pageNumber);
    promise.done(function(){
        show(pageNumber);
    });
    play.find('a')
    .eq(pageNumber)
    .addClass('current')
    .siblings('').removeClass('current');
}

这样可以确保隐藏动画在开始显示动画之前完成。另一种选择是使用内置回调,但我发现这更容易实现。我不确定是否所有的stop语句都是必要的,但保留了它们。

另一个问题(影响初始页面状态的问题)是最初没有隐藏任何内容。要解决这个问题,只需简单地更新init代码如下:

(function(picListLength){
    var playHtml='';
    for(var i=0; i<picListLength; i++){
        playHtml+='<a href="#" data-number="'+i+'">'+(i+1)+'</a>';
    }
    play.html(playHtml);
    hide(0); // hide all but one
})(picList.length);

JSFiddle:http://jsfiddle.net/infiniteloops/CUYbL/

JQuery承诺:http://api.jquery.com/promise/