我有一个简单的动画淡入淡出无序列表中的每个列表项。 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}}。结果是动画重叠。我是一个菜鸟,对于如何处理这个问题毫无头绪,因此动画中不会有任何重叠。有人可以帮忙吗?
答案 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
的额外电话,但希望您能从上述代码中获得重点。