如何让jQuery在完成之前将效果应用于.each()循环中的每个项目?

时间:2010-07-27 12:23:48

标签: javascript jquery jquery-ui

我有以下列表:

<div id="test">test</div>

<ul>
    <li>foo</li>
    <li>bar</li>
    <li>sta</li>
    <li>cko</li>
</ul>

以及以下jQuery代码:

$(document).ready(function() {
    $('li').each(function(index) {
        $('#test').text($(this).text());
        $('#test').show("drop", { direction: "down" }, 500, function() {
            $("#test").delay(1000).hide("puff", {}, 100);
        });
    });  
 });

逻辑上,这应该将div test的内容更改为foo,应用drop and Puff效果,将内容更改为bar,应用效果等等。但是当你运行它时,整个.each循环在效果开始之前就会结束,所以最后一个元素cko首先出现并动画4次。

如何让每个项目获得效果,然后转到下一个项目?

2 个答案:

答案 0 :(得分:2)

如果你希望它按照队列的顺序(使用.queue())发生,你需要在队列中添加第一个函数,如下所示:

$(function() {
    $('li').each(function(index) {
        var li = $(this);
        $('#test').queue(function(n) {
            $(this).text(li.text());            //set the text
            n();                                //call next function in the queue
        }).show("drop", { direction: "down" }, 500, function() {
            $(this).delay(1000).hide("puff", {}, 100);
        });
    });  
 });​

You can give it a try here。这会将文本设置排列为与动画一致的顺序,这似乎是您所追求的。调用传递给你的队列回调的函数很重要,因为这是推进队列的原因,在这种情况下触发后面的动画。

.delay()也会产生一种奇怪的效果,如果你想要它在队列中,就这样做:

$(function() {
    $('li').each(function(index) {
        var li = $(this);
        $('#test').queue(function(n) {
            $(this).text(li.text());
            n();
        }).show("drop", { direction: "down" }, 500)
          .delay(1000).hide("puff", {}, 100);
    });  
 });​

You can try it here,在继续之前,这实际上会为每个元素暂停一秒钟。

答案 1 :(得分:0)

未经测试,但我认为您可以尝试:

$(document).ready(function() {
    animateItem($('li'), 0);
});

function animateItem(li, i) {
    if (li.length > i) {
        $('#test').text(li.eq(i).text());
        $('#test').show("drop", { direction: "down" }, 500, function() {
            $("#test").delay(1000).hide("puff", {}, 100, function() { 
                animateItem(li, i++);
            });
        });
    }
 }