14

我正在构建一个小脚本来为列表设置动画。这是我的html结构:

<ul>
   <li class="slider"> Item-1 </li>
   <li class="slider"> Item-2 </li>
   <li class="slider"> Item-3 </li>
   ...
   <li class="slider"> Item-13 </li>
   <li class="slider"> Item-14 </li>
   <li class="slider"> Item-15 </li>
</ul>

<button> Next </button>

我一次只显示四个里,“下一步”按钮淡出显示的四个里,然后淡入接下来的四个。但是淡化是同时应用的。我尝试在第一次淡入淡出时使用回调函数,但我无法使其工作。

这是脚本:

$('li:gt(3)').css('display', 'none');

//Define the interval of li to display
var start = 0;
var end = 4;

//Get the ul length
var listlength = $("li").length;

$("button").click(function() { 

  // FadeOut the four displayed li 
  $('ul li').slice(start,end).fadeOut(500, function(){

        // Define the next interval of four li to show
        start = start+4;
        end = end+4;

        // Test to detect the end of list and reset next interval
        if( start > listlength ){
          start = 0;
          end = 4;
        }

        //Display the new interval
        $('ul li').slice(start,end).fadeIn(500);
  });    
});

有什么线索吗?

4

2 回答 2

27

问题是每个动画元素调用 .fadeOut() 回调一次,而不是最后一次。您可以修改您的代码以记录它被调用的次数,但更容易 - 假设至少 jQuery 1.6 - 是使用 .promise(),它将在所有相关动画完成后解决:

$(document).ready(function () {
    var $lis = $("li.slider"),
        start = 0;

    $lis.hide()
        .slice(start, start + 4)
        .show();

    $("button").click(function () {
        $lis.slice(start, start + 4)
            .fadeOut(500)
            .promise()
            .done(function () {
                start += 4;
                if (start > $lis.length) {
                    start = 0;
                }
                $lis.slice(start, start + 4).fadeIn();
            });
    });
});

演示:http: //jsfiddle.net/w7Yuk

我对您的代码进行了其他一些更改,例如,使用 li 元素缓存 jQuery 对象,并删除“end”变量。

于 2012-04-17T01:32:30.197 回答
5

我创建了一个不错的jsFiddle 小演示,它修改了您所拥有的内容并为您提供了一个很好的平滑过渡:

HTML:

给按钮一个“下一步”的 id,以便您可以专门针对它,以防页面上还有其他按钮。

<ul>
   <li class="slider"> Item-1 </li>
   <li class="slider"> Item-2 </li>
   <li class="slider"> Item-3 </li>
   <li class="slider"> Item-4 </li>
   <li class="slider"> Item-5 </li>
   <li class="slider"> Item-6 </li>
   <li class="slider"> Item-7 </li>
   <li class="slider"> Item-8 </li>
   <li class="slider"> Item-9 </li>
   <li class="slider"> Item-10 </li>
   <li class="slider"> Item-11 </li>
   <li class="slider"> Item-12 </li>
   <li class="slider"> Item-13 </li>
   <li class="slider"> Item-14 </li>
   <li class="slider"> Item-15 </li>
   <li class="slider"> Item-16 </li>
</ul>

<button id="next"> Next </button>

CSS:

从 display none 开始,这样我们就可以在加载时很好地淡入它们。

.slider { display: none; }
#next { display: none; }

jQuery:

我喜欢缓存元素,所以我开始这样做。然后我淡入前 4 个 LI 元素和下一个按钮。我使用推荐的处理程序.on()来绑定下一个按钮的单击事件。在我们设置之后startend我们调用.fadeOut()下一个按钮和当前的 4 个 LI 元素。现在,你的回调很糟糕的原因是因为它们是你选择器中每个元素的回调(所以 4 次)。相反,我们需要使用.promise()等待它们全部完成,然后我们可以.fadeIn()在下一个按钮和接下来的 4 个 LI 元素上调用该方法。只是一个旁注,我.stop(true,true)用来消除可能存在的任何动画排队。

var $list = $("ul li");
var $next = $("#next");
var start = 0;
var end = 4;

$next.fadeIn(500);
$list.slice(start,end).fadeIn(500);

$next.on("click", function() {

  start += 4;
  end += 4;

  if( start >= $list.length ){
    start = 0;
    end = 4;
  }

  $next.stop(true,true).fadeOut(500);
  $list.stop(true,true).fadeOut(500);

  $list.promise().done(function() {
    $list.slice(start,end).stop(true,true).fadeIn(500);
    $next.stop(true,true).fadeIn(500);
  });

});
于 2012-04-17T01:18:19.467 回答