Завершить анимацию CSS перед изменением страницы с помощью Javascript

#javascript #html #jquery #css

#javascript #HTML #jquery #css

Вопрос:

Я пытаюсь создать простой индикатор загрузки страницы с помощью CSS и немного JS. Я уже создал рабочий css, но проблема в том, что панель отображается после смены страницы, когда я хотел бы, чтобы она сначала завершила анимацию индикатора выполнения css, а затем загрузила следующую страницу.

Код анимации HTML:

 <div class="progress-css"></div>
 

Код анимации CSS:

 :root {
  --progress-duration: 0.8s;
  --progress-height: 2.5px;
  --progress-color: rgb(35,163,255);
  --progress-color-ending: rgba(35,163,255,0.2);
  --progress-shadow: 0 0 3px 2px rgba(0,148,255,0.23);
}

.progress-css {
  position: fixed;
  height: var(--progress-height);
  width: 100%;
  background-color: transparent;
  z-index: 99999;
  box-shadow: none;
  transition: 0.8s;
  animation: progress-load var(--progress-duration);
  -webkit-animation: progress-load var(--progress-duration);
  animation-timing-function: ease-in-out;
}

@keyframes progress-load {
  0% {
    background-color: var(--progress-color);
    box-shadow: var(--progress-shadow);
    width: 0%;
  }
  20% {
    background-color: var(--progress-color);
    width: 20%;
  }
  25% {
    background-color: var(--progress-color);
    width: 28%;
  }
  90% {
    background-color: var(--progress-color);
    width: 85%;
  }
  100% {
    width: 100%;
    background-color: var(--progress-color-ending);
    box-shadow: none;
  }
}
 

Теперь, когда я нажимаю на <a href="subpage.html">Redirect</a> тег на веб-сайте, он загружает указанную страницу, а затем отображает анимацию прогресса. Я бы хотел, чтобы сначала отображалась анимация прогресса, а затем загружалась следующая страница.

Я был бы благодарен за ответ на мой вопрос.

Комментарии:

1. Итак, в основном у вас есть загрузчик?

2. @DumbCoder7 Да, это загрузчик, отображаемый в виде индикатора выполнения вверху страницы. Если вы не понимаете, что я имею в виду, зайдите на YouTube и переключайтесь между страницами, вы увидите красную панель загрузки вверху страницы каждый раз, когда вы переключаете страницу.

3. Если у вас есть фиксированная продолжительность перехода, почему бы не запросить загрузку страницы после этой продолжительности?

Ответ №1:

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

 document.querySelector('.progress-css').addEventListener('animationend', e=>{
    //go to next page or similar
    window.location.href = 'subpage.html';
});
 

Обновленный пример, основанный на более подробной информации из комментариев:

 const progressBar = document.querySelector('.progress-css');

//add a listener to all of the links; modify the query if it should be restricted to specific links
document.querySelectorAll('a').forEach(link => {
  link.addEventListener('click', e => {
    e.preventDefault(); //stop the default behavior of navigating to a link when clicking an <a> tag
    setupLoadingBar( link.href );
  });
});

const setupLoadingBar = url => {
  const cleanupLoadingBarAndNavigate = e => {
    progressBar.removeEventListener('animationend', cleanupLoadingBarAndNavigate); //removing this each time is important to ensure that it doesn't run multiple times if you don't actually navigate away

    progressBar.classList.remove('loading');
   
    alert('Navigate to: ' url);

    //uncomment this to actually navigate to the url
    //window.location.href = url;
  }
  
  progressBar.classList.add('loading');
  progressBar.addEventListener('animationend', cleanupLoadingBarAndNavigate);
} 
 :root {
  --progress-duration: 4s;
  --progress-height: 2.5px;
  --progress-color: rgb(35,163,255);
  --progress-color-ending: rgba(35,163,255,0.2);
  --progress-shadow: 0 0 3px 2px rgba(0,148,255,0.23);
}

.progress-css {
  position: fixed;
  height: var(--progress-height);
  width: 100%;
  background-color: transparent;
  z-index: 99999;
  box-shadow: none;
  transition: 0.8s;
  display:none;
}

.loading {
  display:block;
  animation: progress-load var(--progress-duration);
  -webkit-animation: progress-load var(--progress-duration);
  animation-timing-function: ease-in-out;
}

@keyframes progress-load {
  0% {
    background-color: var(--progress-color);
    box-shadow: var(--progress-shadow);
    width: 0%;
  }
  20% {
    background-color: var(--progress-color);
    width: 20%;
  }
  25% {
    background-color: var(--progress-color);
    width: 28%;
  }
  90% {
    background-color: var(--progress-color);
    width: 85%;
  }
  100% {
    width: 100%;
    background-color: var(--progress-color-ending);
    box-shadow: none;
  }
} 
 <a href="about.html">About</a>
<a href="contact.html">Contact</a>

<div class="progress-css"></div> 

Комментарии:

1. Спасибо за ваш ответ, но что, если у меня на моем сайте несколько ссылок? Кроме того, когда я запускал этот код, он создавал бесконечный цикл перенаправления на subpage.html чередование с анимацией индикатора выполнения.

2. @talaing, можете ли вы подробнее объяснить, что вы подразумеваете под «загрузкой» в данном случае? Вы пытаетесь выполнить какую-то предварительную загрузку, когда ссылка загружается через JavaScript / AJAX в фоновом режиме, или просто хотите отобразить анимацию перед сменой страниц, чтобы создать иллюзию загрузки чего-либо? (Это действительный метод UX; не стыдно подделывать его.) Если это первое (предварительная загрузка), это далеко выходит за рамки вопроса SO. Однако я могу больше помочь с последним.

3. Не нужно предварительно загружать указанную страницу в фоновом режиме — я просто хочу создать иллюзию загрузки чего-либо.

4. @talaing обновил ответ новым примером кода, который показывает, как это сделать с помощью нескольких ссылок