用于for循环动画的nav控件

时间:2013-07-15 11:16:09

标签: javascript jquery animation

我有一个简单的动画淡入淡出无序列表中的每个列表项。 HTML标记如下:

<ul>
  <li>first par</li>
  <li>second par</li>
  <li>third par</li>
</ul>

<div></div>

空div将包含通过jquery动态导航控件的按钮。

脚本如下:

<script>

var ul = $('ul'), li = $('ul li'), li_length = li.length, div = $('div');

//hides all list items
li.hide();

function play (eq){
  eq = (eq===undefined) ? 0 : eq; 

  for(i=eq, d=0; i<li_length; i++, d+=3000){
    li.eq(i).delay(d).fadeIn(1000).delay(1000).fadeOut(1000);
  }
}

//This dynamically appends the nav buttons in the div
li.each(function(i){
  div.append('<button> '+ i + '</button>');
})

//the normal animation going through each list item, fading in and out
play();

var btn = $('div button');

//each button when clicked should animate the corresponding list item (fadein and out), then the next 
li.each(function(i){
   btn.eq(i).click(function(){
     li.stop(true, true);
     li.hide();
     play(i);
   })
})

</script>

play()运行时,它就能完成工作。但是,当您单击任何导航按钮时,例如第二个列表项正在播放然后你单击按钮1(本质上调用play(1)),for循环(来自play())仍然似乎正在播放虽然我已使用{{停止了所有列表项的动画1}}。结果是动画重叠。我是一个菜鸟,对于如何处理这个问题毫无头绪,因此动画中不会有任何重叠。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

无论您停止当前动画,

delay都将继续运行:

  

.delay()方法最适合延迟排队的jQuery效果。因为它是有限的 - 例如,它没有提供取消延迟的方法 - .delay()不能替代JavaScript的本机setTimeout函数,这可能更适合某些用例。

而不是delay您应该使用setTimeout并在click处理程序中取消它:

var timeoutId = setTimeout(function() { [fadeIn/fadeOut] }, delayDuration);

然后从你的click处理程序:

btn.eq(i).click(function() {
    ...
    clearTimeout(timeoutId);
});

运行play设置的方式,您需要为每个li动画设置和取消超时。

<强>修订

使用setTimeout,您的部分代码可以按如下方式重写:

function play (eq){
    var
        eq = eq || 0,
        i, d; 

    for(i=eq, d=0; i<li_length; i++, d+=3000){

        // store the timeoutID returned by setTimeout on the li itself
        li.data('timeoutId', setTimeout(function() {
                li.eq(i).fadeIn(1000).delay(1000).fadeOut(1000);
            }, d)
        );
    }
}

然后在你的click处理程序中:

li.each(function(i){
    btn.eq(i).click(function(){
        li.stop(true, true);
        li.hide();

        // grab the timeoutId and clear it
        clearTimeout(parseInt(li.data('timeoutId'), 10));

        play(i);
    });
});

setTimeout / delay之间的fadeIn可能还需要fadeOut的额外电话,但希望您能从上述代码中获得重点。