Не работает JQuery fadeOut/fadeIn

i m построим немного script для анимации списка. Вот моя структура 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 за один раз, "следующая" кнопка fadeOut отображается четыре li et fadeIn в следующих четырех. Но замирания применяются одновременно. Я попытался использовать функцию обратного вызова при первом исчезновении, но я не могу заставить его работать.

здесь находится script:

$('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);
  });    
});

Любые подсказки?

Ответ 1

Проблема заключается в том, что обратный вызов .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

Я сделал еще пару изменений вашего кода, например, кеширование объекта jQuery с элементами li и удаление переменной "end".

Ответ 2

Я создал небольшую небольшую jsFiddle demo, которая изменяет то, что у вас есть, и дает вам приятный плавный переход:

HTML:

Дайте кнопке идентификатор "next", чтобы вы могли настроить таргетинг на него, в случае, если на странице есть другие кнопки.

<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

Начните с выключения с дисплеем, чтобы мы могли легко их сгладить при загрузке.

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

JQuery

Мне нравится кэшировать элементы, поэтому я начал с этого. Затем я исчезаю как в первых 4 элементах LI, так и в следующей кнопке. Я использую рекомендуемый обработчик .on(), чтобы связать событие click следующей кнопки. После того, как мы установили start и end, мы вызываем .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);
  });

});