Я надеюсь создать анимацию перехода текста с использованием JQuery и столкнулся с проблемой синхронизации. Я осмотрел некоторые другие темы и не смог найти правильного решения для того, чего я пытаюсь достичь. Вот HTML-код, который у меня есть:

<div id="t1">
    <span>T</span>
    <span>H</span>
    <span>I</span>
    <span>S</span>
</div>
<div id="t2">
    <span>T</span>
    <span>H</span>
    <span>A</span>
    <span>T</span>
</div>

JS:

function showMessage(obj, up){
    if(dir){
        $(obj).children().each(function(i, el) {
            setTimeout(function() {
                $(el).animate({
                    'opacity': 1.0,
                    'top': '0px'
                }, 450);
            }, 500 + (i * 150));
        });
    } else {
        $(obj).children().each(function(i, el) {
            setTimeout(function() {
                $(el).animate({
                    'opacity': 0,
                    'top': '-30px'
                }, 450);
            }, 3000 + (i * 150));
        });
    }
}
showMessage("#t1", true);
showMessage("#t1", false);
showMessage("#t2", true);
showMessage("#t2", false);

И THIS, и THAT отображаются одновременно. Как сделать так, чтобы второе не отображалось, пока первое полностью не исчезло?

Демо: jsfiddle

0
M. Bloom 16 Дек 2015 в 09:01

3 ответа

Лучший ответ

Ты можешь их приковать?

showMessage("#t1", true, function(){
  showMessage("#t1", false, function(){
    showMessage("#t2", true, function(){
       showMessage("#t2", false, function(){});
    });
  });
});

А затем включите счетчики в ваше showMessage, чтобы проверить, были ли отображены все пролеты

    function showMessage(obj, up, callback){
    var counter = 1;
    var numberOfChildren = $(obj).children().size();
    if(up){
        $(obj).children().each(function(i, el) {
            setTimeout(function() {
                $(el).animate({
                    'opacity': 1.0,
                    'top': '0px'
                }, 450, function(){
                counter++;
                console.log(counter);
                if ( counter == numberOfChildren )
                {
                    callback();
                }
            });
            }, 500 + (i * 150));
        });
    } 
    else {
        $(obj).children().each(function(i, el) {
            setTimeout(function() {
                $(el).animate({
                    'opacity': 0,
                    'top': '-30px'
                }, 450, function(){
                counter++;
                console.log(counter);
                if ( counter == numberOfChildren )
                {
                    callback();
                }
            });
            }, 3000 + (i * 150));
        });
    }
}
$(function() {
   showMessage(".dev", true, function(){
    showMessage(".dev", false, function(){
      showMessage(".dev2", true, function(){
         showMessage(".dev2", false, function(){});
      });
    });
  });
});

Обновлен dir до up.

1
gurvinder372 16 Дек 2015 в 06:57

SetTimeout выполняется в вакууме. Анонимная функция не знает о ваших внешних переменных i и el

0
Andrey 16 Дек 2015 в 06:09

Попробуйте заменить .delay() на setTimeout, вызывая второй набор анимаций, когда i равен общему количеству .length первого набора анимаций в .each(), вызванного {{X5) }} .children(): span элементов

function showMessage(obj, dir) {
  var first = obj[0], second = obj[1];
  $(first).children().each(function(i, el) {
    $(el).delay(500 + (i * 150)).animate({
      "opacity": 1.0,
      "top": "0px"
    }, 450, function() {
      // when all `first` : `#t1` `span` animations complete,
      // call `next` with `second`:`#t2` as parameter
      if (i === first.length) next(second)
    });
  });
  var next = function(elems) {
    $(elems).children().each(function(i, el) {
      $(el).delay(3000 + (i * 150)).animate({
        "opacity": 0,
        "top": "-30px"
      }, 450);
    });
  }
}
showMessage(["#t1", "#t2"]);
#t1 span {
  opacity: 0;
  top: 30px;
}
#t2 span {
  opacity: 1;
  top: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id="t1">
  <span>T</span>
  <span>H</span>
  <span>I</span>
  <span>S</span>
</div>
<div id="t2">
  <span>T</span>
  <span>H</span>
  <span>A</span>
  <span>T</span>
</div>
0
guest271314 16 Дек 2015 в 06:34