Анимация очереди элементов, переход к конечному элементу - PullRequest
3 голосов
/ 06 марта 2019

CodePen

Правила:

  • Каждый щелчок добавляет элемент <progress>.
  • Каждый индикатор выполнения будет анимирован до полного.
  • Анимации не начнутся, пока не закончится предыдущий.

Проблема:

Если вы быстро нажмете, он будет анимировать только последний progress бар.А анимация должна происходить одна за другой до завершения.

Вопрос:

При быстром нажатии почему анимации не работают?

HTML:

<div class="container">
  <div class="add-progress-container">
    <input class="input-seconds" type="number" min="1" max="10" value="1">
    <button class="add-progress">Add progress</button>
  </div>  
  <div class="progress-container"></div>
</div>

JS:

const container = document.querySelector('.progress-container');
const inputSeconds = document.querySelector('.input-seconds');
const addBtn = document.querySelector('.add-progress');
let animating = false;


function animateProgress(duration, el) {
  const intervalId = setInterval(() => {
    if(el.value >= el.max) {
      animating = false;
      window.clearInterval(intervalId);
      console.log('finished');
      checkQueue();
      return;
    }

    el.value += el.max/duration;
  }, 1000);
} 


function getSeconds() {
  return parseInt(inputSeconds.value, 10);
}

let progressCount = 0;

function createProgress() {
  const template = `<progress data-progress="${progressCount}" value="0" max="100"></progress>`;
  container.innerHTML += template;
  const el = document.querySelector(`[data-progress="${progressCount}"]`);
  progressCount++;
  return el;
}

let queue = [];
function addProgress() {
  const el = createProgress()
  queue.push(el);
  checkQueue();
}

function checkQueue() {
  if(queue.length && !animating) {
    animating = true;
    animateProgress(getSeconds(), queue.shift());
  }  
}

addBtn.addEventListener('click', addProgress);

1 Ответ

2 голосов
/ 06 марта 2019

Назначение innerHTML+= воссоздает все предыдущие элементы в элементе контейнера, это означает, что ваши ссылки на другие элементы progress больше не соответствуют фактическим элементам, которые создает это назначение.

Вы должны добавитьновый элемент прогресса, подобный этому:

function createProgress() {
  const el = document.createElement("progress");
  el.setAttribute("data-progress", progressCount);
  el.setAttribute("value", 0);
  el.setAttribute("max", 100);
  container.appendChild(el);
  return el;
}

Как прокомментировал Макюу ниже, количество шагов для отдельных элементов прогресса выполняется только при запуске их анимации.Это означает, что если вы измените входное значение, оно будет применено также к ранее созданным элементам (когда они еще не начали анимацию).

Если предполагается использовать количество шагов, как они были указаны в момент создания элемента , затем измените две строки в вашем коде:

queue.push([getSeconds(), el]);

и:

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