В течение дня у меня возникла очень странная проблема с моим набором анимаций jQuery.
Я попробовал несколько подходов, но все они просто дают мне странные ошибки.
Я сделал jsfiddle для моего примера. Пожалуйста, проверьте console.log, а также попробуйте увидеть анимацию, выполняемую в html, и это очень странно.
У меня есть меню, которое сначала закрывает ящик, сначала затухая текст внутри, а затем открывает еще один ящик и затухает каждую строку текста за раз.
Я пытаюсь заблокировать возможность щелчка по другому элементу меню, пока еще есть анимация.
Я также попытался использовать .promise().done(function(){...
с каждой функцией, но это не сработало.
Мой файл js
$(document).ready(function(){
var ongoing=false;
var selected="one";
$("ul li").click(function(){
console.log("ongoing : " +ongoing);
if($(this).index() == 1 && selected != "two" && !ongoing ){
console.log("clicked two and in");
console.log(ongoing);
ongoing=true;
var text=$("ul li:nth-child(1)").text();
console.log(text);
$("."+selected+" div").animate({"opacity": 0},1000,function(){
$("."+selected).animate({'width': '0px'},1000,function(){
$("."+selected).hide();
$(".extra").animate({"color": "blue"},1000);
$("."+text).show().animate({'width': '800px'},1000,function(){
selected=text;
$("."+selected+" div").each(function(i){
$(this).delay(i*2000).animate({"opacity": 1},2000,function(){
console.log(i + " is finished");
if(i == 2){
ongoing=false;
}
});
});
});
});
});
}
else if($(this).index() == 2 && selected != "three" && !ongoing){
console.log("clicked about and in");
console.log(ongoing);
ongoing=true;
var text=$("ul li:nth-child(2)").text();
console.log(text);
$("."+selected+" div").animate({"opacity": 0},1000,function(){
$("."+selected).animate({'width': '0px'},1000,function(){
$("."+selected).hide();
$(".extra").animate({"color": "red"},1000);
$("."+text).show().animate({'width': '800px'},1000,function(){
selected=text;
$("."+selected+" div").each(function(i){
$(this).delay(i*2000).animate({"opacity": 1},2000,function(){
console.log(i + " is finished");
if(i == 2){
ongoing=false;
}
});
});
});
});
});
}
});
});
Мой html файл
<div class='extra'> Hi</div>
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
<div id="content">
<div class='one'>
<div class='one-1'>test test test test</div><br>
<div class='one-2'>test test test test</div><br>
<div class='one-3'>test test test test</div><br>
</div>
<div class='two'>
<div class='two-1'>test test test test</div><br>
<div class='two-2'>test test test test</div><br>
<div class='two-3'>test test test test</div><br>
</div>
<div class='three'>
<div class='three-1'>test test test test</div><br>
<div class='three-2'>test test test test</div><br>
<div class='three-3'>test test test test</div><br>
</div>
</div>
Мой css файл
ul li{
display:inline-block;
background: red;
cursor: pointer;
}
#content{
width:100%;
}
.three{
margin: 0 auto;
width: 0px;
display: none;
height: 360px;
text-align: center;
background: #EEE836;
font-size: 50px;
margin-bottom: 180px;
}
.two{
margin: 0 auto;
width: 0px;
display: none;
height: 360px;
text-align: center;
background: blue;
font-size: 50px;
margin-bottom: 180px;
}
.one{
margin: 0 auto;
width: 800px;
margin-bottom: -180px;
height: 360px;
background: white;
text-align: center;
background: red;
font-size: 50px;
}
(1) Когда вы анималируете несколько элементов одновременно, вы хотите, чтобы обратный вызов вызывался только один раз после завершения последней анимации.
Чтобы выполнить это, у вас есть следующее:
$("."+selected+" div").animate({"opacity": 0},1000,function(){
Вы можете изменить его на:
$("."+selected+" div").animate({"opacity": 0},1000).promise().done(function(){
Я получил эту технику из qaru.site/questions/139238/....
(2) Прежде чем вы увянете что-то, вы должны сначала убедиться, что он начинается как полностью исчез. Аналогично, перед тем, как вы покажете элемент, а затем увеличьте его ширину, вы должны убедиться, что он сначала имеет ширину 0. Эти изменения могут быть сделаны с помощью функции .css()
и должны выполняться перед вызовом .show()
.
Например, если у вас есть:
$("."+text).show().animate({'width': '800px'}...
Вы должны иметь:
$("."+text).css({'width': '0px'}).show().animate({'width': '800px'}...
(3) Вместо использования (хотя и более простой) метода использования .delay()
для анимирования списка элементов последовательно, следующий метод дает лучшие результаты:
var i = 0;
(function() {
var $el = $($elements[i++] || []);
if ($el.length > 0) {
$el.animate({ opacity: 1 }, 2000, arguments.callee);
} else {
// Perform final tasks.
}
})();
Я адаптировал эту технику отсюда.