JQuery fadeOut/обратный вызов fadeIn не работает
Я создаю небольшой скрипт для анимации списка. Вот моя структура 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>
Я показываю только четыре ли за один раз, кнопка "next" исчезает, отображаемые четыре li et fadeIn следующие четыре. Но исчезает применяют оба вместе. Я попытался использовать функцию обратного вызова на первом затухании, но я не могу заставить ее работать.
вот этот скрипт:
$('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);
});
});
какие-то зацепки?
2 ответов
проблема в том, что .затухания() обратного вызова вызывается один раз для каждого анимированного элемента, а не один раз в конце. Вы можете изменить свой код, чтобы сохранить счетчик того, сколько раз он был вызван, но гораздо проще - предполагая, по крайней мере, 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".
я создал маленький демо jsFiddle это изменяет то, что у вас было, и дает вам приятный плавный переход:
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:
начните оба с отображения none, чтобы мы могли красиво их выцветать при загрузке.
.slider { display: none; }
#next { display: none; }
jQuery:
мне нравится кэшировать элементы, поэтому я начал с этого. Затем я исчезаю как в первых 4 LI элементах, так и в следующей кнопке. Я использую рекомендуемый обработчик .on()
для привязки события click кнопки next. После того, как мы установили start
и end
мы называем .fadeOut()
на следующей кнопке и текущих 4 LI элементах. Теперь причина, по которой ваш обратный вызов является винтовым, связана с тем, что они являются обратным вызовом для каждого элемента в вашем селекторе ( так 4 раза ). Вместо этого нам нужно использовать .promise()
ждать, пока все они завершатся в целом, а затем мы можем вызвать .fadeIn()
способ на кнопку Next и в следующем 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);
});
});