jQuery: анимация происходит одновременно, а не последовательно с .each () - PullRequest
0 голосов
/ 07 мая 2018

Я перебираю массив объектов класса ".mini". Для каждого объекта каждый объект будет ждать 500 миллисекунд (функция setTimeout), прежде чем двигаться (вызывая функцию go). Например,

function iterate() {
    $(".mini").each(function(index)
    {
        var element = $(this);
        setTimeout(function() {go(element)}, 500);
    });
}

function go(element) {
    element.animate({left: "500px"},200);
}

Однако анимация для каждого элемента происходит одновременно (все 32 объекта .mini движутся одновременно), а не один движется за другим. Как это может быть так, что первый начинает двигаться через 500 секунд после старта, второй начинается после 1000 секунд от старта и т. Д.

Ответы [ 3 ]

0 голосов
/ 07 мая 2018

Используйте Promise с и reduce. Дождитесь начала следующей анимации, пока не закончится предыдущая.

Если вы хотите дождаться начала начальной анимации, оберните всю цепочку в setTimeout().

Array.from(document.querySelectorAll("ul > li")).reduce((prev, curr) => {
  return prev.then(function() {
    return new Promise((resolve, reject) => {
      $(curr).animate({
        opacity: 0.2
      }, 1000, function() {
        resolve();
      });
    });
  });
}, Promise.resolve());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
  <li>Hello</li>
  <li>Hello</li>
  <li>Hello</li>
  <li>Hello</li>
  <li>Hello</li>
  <li>Hello</li>
</ul>
0 голосов
/ 07 мая 2018

Все они происходят одновременно, потому что все setTimeout вызываются внутри each, что не займет много времени для зацикливания списка элементов (всего несколько миллисекунд).Если вы хотите связать их, используйте обратный вызов complete, равный jQuery#animate, чтобы подать сигнал на запуск следующей анимации:

function iterate() {
    var $list = $(".mini"),                                // get the whole list of elements
        i = 0;                                             // i is the index of the currently animated element from list

    function next() {                                      // the function that when called will get the current element from list (if exists) and starts that element's animation
        if(i < $list.length) {                             // if there is still un-animated elements in $list
            setTimeout(function() {                        // animate the current element
                go($list.eq(i), next);                     // specify that next will be called when the current element's animation is done
            }, 500);
            i++;                                           // increment i of course
        }
    }

    next();                                                // call next to start the magic
}

function go(element, complete) {                           // go will take an element to be animated, and a function that will be called when that animation is done
    element.animate({left: "500px"}, 200, complete);       // simply call animate with that additional function (see jQuery#animate docs)
}
0 голосов
/ 07 мая 2018

Вы должны умножить 500 на index + 1, чтобы первое произошло в 500ms, второе в 1000ms и т. Д.

setTimeout(function() {go(element)}, 500 * (index + 1));

Прямо сейчас вы перебираете все из них и говорите каждому из них 500ms from now, do this. Итак, 500ms с этого момента каждый из них делает это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...