#css #loops #animation #css-transitions #slideshow
Вопрос:
Я работал над этой страницей карусели (которая запускается кнопкой «ввод» на целевой странице). Он пролистывается просто отлично до тех пор, пока не завершится первый цикл, после чего анимация стекается (пока страница не перегрузится).
Это в основном неупорядоченный список <ul>
внутри основного <div>
, в котором перечислены изображения и видео.
В ДВУХ СЛОВАХ, мои анимации запускаются правильно, и мои классы хорошо переносятся во время первого цикла. Но во втором цикле что-то происходит. Первая страница отображается правильно, но второй элемент исчезает, потому что анимация, которая его вызывает, запускается дважды (проверяется путем добавления 'animationstart'
журнала консоли).
ФУНКЦИИ:
- При входе из функции целевой страницы
enterPage()
:- первый элемент, представляющий собой видео, отображается и воспроизводится; затем
- прослушиватель
'ended'
событий, который затем запускаетflipCurrentToNext()
функцию.
- Функция
flipCurrentToNext()
:- обновляет переменные
currentPage
и anextPage
; - приостанавливает
currentPage
, если это видео (firstPage
это видео); - добавляет класс перехода, который переворачивает
currentPage
влево; - отображает и анимирует
nextPage
переход в видовое окно справа; - он воспроизводит видео, если это видео, и просто отображает, если это фотография;
- добавляет в
'animationend'
списокnextPage
событий , который затем:
а) удаляет переход и.current-page
класс из перевернутогоcurrentPage
состояния ;
б) добавляет.current-page
класс вnextPage
;
в) обновляетcurrentPage = nextPage
;
г) обрабатывает перевернутую страницу какcurrentPage
;
д) вызывает функцию, котораяautoFlip()
проходит через карусель.
- обновляет переменные
flipLastToFirst()
функция выполняет то же самое, что и № 2, за исключением:nextPage
обменивается сfirstPage
и;- это
autoFlip()
не запускается, потому что каким-то образомenterPage()
функция все еще запускает'ended'
прослушиватель событий видео.
- There are click handlers on transparent divs that users can use. I’m still not sure how I want these to override the
autoFlip()
s. (not really part of my question, but if you do have the answer, I’d love to know it!) - There are also other functions like
flipToPrevious()
,flipFirstToLast()
, but they’re basically the same as above.
THE CODE:
function enterPage() {
//some code that deals with the landing page
let cover = document.querySelector('.firstPage');
cover.style.display = "block";
cover.play();
cover.addEventListener('ended', () => {
flipCurrentToNext();
return;
})
return;
//I thought adding return would somehow close the eventlistener.
//I initially explored the possibility that 'ended' was also
//simultaneously calling flipToNext(), causing the
//animation overload.
}
let currentPage =
content.querySelector('.current-page');
let nextPage =
currentPage.parentElement.nextElementSibling.childNodes[1];
function autoFlip() {
currentPage = content.querySelector('.current-page');
if (currentPage.parentElement.nextElementSibling == null) {
flipLastToFirst();
} else {
flipCurrentToNext();
}
clearTimeout();
return;
}
function flipCurrentToNext() {
currentPage =
content.querySelector('.current-page');
nextPage =
currentPage.parentElement.nextElementSibling.childNodes[1];
//updates variables to stay current
if (currentPage.childNodes[1].type == "video/mp4") {
currentPage.pause();
//I suspected if this triggers the 'ended'
//eventlistener. Will it? If it does, how do I go around it?
//I couldn't figure out how to integrate
//a removeEventListener.
currentPage.currentTime = 0;
}
currentPage.classList.add('flipOutLeft')
//This transition class flips the current page out.
nextPage.style.display = "block";
nextPage.style.animation = "flipInRight 0.77s";
//THIS is the animation that gets triggered twice after
//the first loop. Then it stacks. I've console logged
//nextPage, its classes and its IDs. It is one and the same.
//
//This animation is what flips the next page into the viewport.
nextPage.addEventListener('animationend', () => {
currentPage.style.display = "none";
currentPage.classList.remove('flipOutLeft');
currentPage.classList.remove('current-page');
nextPage.classList.add('current-page');
currentPage = nextPage;
//above is an initial solution to handling fast clicks
//not final
if (currentPage.childNodes[1].type == "video/mp4") {
currentPage = content.querySelector('.current-page');
currentPage.play();
currentPage.addEventListener('ended', () => {
autoFlip(); //<--AUTOFLIP CALL for videos
return;
})
} else {
setTimeout(autoFlip, 5555); //<--for photos
}
return;
})
return;
}
//This is the CLICK handler.
flipRight.addEventListener('click', () => {
clearTimeout(autoFlip());
currentPage = content.querySelector('.current-page');
currentPage.removeEventListener('ended', flipCurrentToNext());
//I can't tell if this helped.
if (currentPage.classList.contains('lastPage') == true) {
flipLastToFirst();
} else {
flipCurrentToNext();
}
})
//I've console-logged the hell out of the code.
//I couldn't find where I'm going wrong.
//JUST IN CASE you need to see the LastToFirst function:
function flipLastToFirst() {
currentPage = content.querySelector('.current-page');
let firstPage = currentPage.parentElement.parentElement.firstElementChild.childNodes[1];
if (currentPage.childNodes[1].type == "video/mp4") {
currentPage.pause();
currentPage.currentTime = 0;
muteButton.style.visibility = "hidden";
}
currentPage.classList.add('flipOutLeft');
firstPage.style.display = "block";
firstPage.style.animation = "flipInRight 0.77s";
firstPage.addEventListener('animationend', () => {
currentPage = content.querySelector('.current-page');
currentPage.style.display = "none";
currentPage.classList.remove('flipOutLeft');
currentPage.classList.remove('current-page');
firstPage.classList.add('current-page');
currentPage = content.querySelector('.current-page');
firstPage.play();
muteButton.style.visibility = "visible";
return;
})
return;
}
.carousel__content { /*Unordered List*/
padding: 0;
margin: 0;
list-style-type: none;
overflow: hidden;
height: 100vh;
}
.carousel__page { /*List Item*/
height: 100vh;
float: left;
}
.carousel__page-item {
position: absolute;
display: none;
height: 100vh;
transition: all 0.55s ease-out;
animation: all ease-out;
animation-iteration-count: 1; /*I tried - didn't work*/
}
.flipOutLeft { /*Applied transition*/
transform: translate(-150%, 0);
opacity: 0;
@keyframes flipInRight { /*Applied animation*/
0% {transform: translate(200%, 0)};
100% {transform: translate(0, 0)};
<main>
<!--transparent navigation <buttons>-->
<div>
<ul class="carousel__content">
<li class="carousel__page">
<!--THIS VIDEO is what starts the carousel-->
<video class="carousel__video carousel__page-item
firstPage current-page" preload="auto" autoplay="true">
<source src="" type="video/mp4">
</video>
</li>
<li>
<picture class="carousel__image carousel__page-item">
<img /></picture>
</li>
<!--More are added just like this last picture.-->
</ul>
</div>
</main>
Как бы мне ни хотелось, чтобы это было кратко, я также не хотел утаивать соответствующую информацию. Я, очевидно, не могу найти дыру. Я провел много исследований, но мне кажется, что я просто не вижу проблему должным образом.
Я начал писать код месяц назад, и я определенно чувствую, что у меня с головой все в порядке.
P.S. Я на 100% уверен, что в коде есть ненужные строки — не стесняйтесь указывать на них.
Комментарии:
1. на данный момент, как мне кажется, ваш обработчик событий для animationend добавляется несколько раз. Возможно, потребуется удалить. Попытаюсь воссоздать в песочнице с кодом или что-то в этом роде.