На моем элементе у меня работает CSS-анимация, если у нее есть определенный класс (wiggle), и переход, как только у него есть другой (right):
<div class = "outer">
<div class = "inner wiggle"></div>
</div>
@keyframes wiggle {
from {
left: 10%;
}
50% {
left: 30%;
}
to {
left: 10%;
}
}
.inner {
left: 0;
&.wiggle {
animation: wiggle 2s infinite;
}
&.right {
left: 90%;
transition: left 2s;
}
}
Теперь, если удалить класс wiggle и одновременно добавить right, переход не будет воспроизведен; left: 90% применяется немедленно. Однако, если между удалением первого и добавлением второго есть задержка, переход произойдет должным образом.
Вот JSFiddle, иллюстрирующий проблему.
Похоже, что при переходе из анимации значения (такие как left в данном случае) не имеют явного значения для перехода, поэтому они просто отображаются в свое окончательное состояние.
Это ожидаемое поведение, т.е. часть спецификации? Или браузеры свободны, как справиться с этим случаем?
Я тестировал последние версии Firefox и Chromium.
Разъяснение:Я в основном не ищу обходные пути, особенно не сложные, но скорее по той причине, что Зачем именно браузеры ведут себя так же, как они.
Я думаю, что это может быть ошибка в рендеринге браузера или около того, но если вам нужно решение, я могу дать вам его с transform.!
@Jeremy, первый выглядит так, как будто он вызван тем же поведением, но не совсем той же проблемой, а второй немного отличается, по крайней мере, это решение, которое применимо в моем случае.
@weBBer Ну, я пытаюсь проделать то же самое и с другими свойствами, left был просто самым простым для визуализации и изолирования проблемы. Например, для opacity такого обходного пути нет.
@CedricReichenbach Я не имел в виду ту же проблему, извините. Но я думаю, что у обоих была одна и та же причина. Поскольку у вас не может быть animation и transition на одном элементе.






Я думаю, что это может быть ошибка в рендеринге браузера или около того, но если вам нужно решение, я могу дать вам один альтернативный метод с transform.
Рабочая рабочий пример для вас:
$('#toggle').click(() => {
$('.inner').removeClass('wiggle').addClass('right');
});@keyframes wiggle {
from {
left: 10%;
}
50% {
left: 30%;
}
to {
left: 10%;
}
}
.outer {
height: 5em;
background-color: black;
position: relative;
}
.inner {
height: 100%;
width: 10%;
position: absolute;
transform: translate(0%);
background-color: green;
transition: transform 2s ease-in-out;
}
.inner.wiggle {
animation: wiggle 2s infinite;
}
.inner.right {
transform: translate(900%);
}<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>
Animated
</h2>
<div class = "outer">
<div class = "inner wiggle"></div>
</div>
<h2>
Not animated
</h2>
<div class = "outer">
<div class = "inner"></div>
</div>
<hr>
<button id = "toggle">
move right
</button>Надеюсь, это было полезно для вас.
Как упоминалось в другом моем комментарии, это всего лишь обходной путь с использованием других свойств CSS. Однако я ищу общее решение, подходящее для любой собственности.
@CedricReichenbach понял, братан. Кто-нибудь может предложить вам общее решение, чтобы оно также могло мне помочь :)
Его внешний вид - это ожидаемое поведение. Я думаю, что когда вы добавляете класс right с left:90%, он не может выбрать начальное значение для свойства css left. В качестве альтернативы вы можете создать еще один ключевой кадр для класса .right.
$('#toggle').click(() => {
$('.inner').removeClass('wiggle').addClass('right');
});@keyframes wiggle {
0% {
left: 10%;
}
50% {
left: 30%;
}
100% {
left: 10%;
}
}
@keyframes right {
100% {
left: 90%;
}
}
.outer {
height: 5em;
background-color: black;
position: relative;
}
.inner {
height: 100%;
width: 10%;
position: absolute;
left: 0;
background-color: green;
transition: left 2s;
}
.wiggle {
animation: wiggle 2s infinite;
}
.right {
animation: right 2s forwards;
}<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>
Animated
</h2>
<div class = "outer">
<div class = "inner wiggle"></div>
</div>
<h2>
Not animated
</h2>
<div class = "outer">
<div class = "inner"></div>
</div>
<hr>
<button id = "toggle">
move right
</button>Этот обходной путь может вам помочь, идея состоит в том, чтобы использовать css переменные, идея состоит в том, чтобы установить анимацию с альтернативной функцией, поэтому в этом случае нам понадобятся только From и To ... с другой стороны, нам нужно настроить и событие для каждой итерации, таким образом мы знаем, когда итерация заканчивается,
Итак, когда мы нажимаем кнопку, вы можете изменить значение переменной и удалить класс ...
$('#toggle').click(() => {
$('.inner').addClass('right');
});
let flag = false;
$(".inner").on("animationiteration webkitAnimationIteration oAnimationIteration MSAnimationIteration", function(){
flag && $(".inner").removeClass('wiggle');
if ($(".inner").hasClass('right')) flag = true;
});:root {
--from: 10%;
--to: 30%;
}
@keyframes wiggle {
from {
left: var(--from);
}
to {
left: var(--to);
}
}
.outer {
height: 5em;
background-color: black;
position: relative;
}
.inner {
height: 100%;
width: 10%;
position: absolute;
transform: translate(0%);
background-color: green;
transition: transform 2s ease-in-out;
left:90%;
}
.inner.wiggle {
left:10%;
animation: wiggle 1s infinite;
animation-direction: alternate;
}
.inner.right {
--to:90%;
animation-direction: normal;
animation-duration:2s;
}<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>
Animated
</h2>
<div class = "outer">
<div class = "inner wiggle"></div>
</div>
<hr>
<button id = "toggle">
move right
</button>Учтите, что это ошибка, когда анимация возвращается в начальную точку ...
Хм, интересный подход; поэтому вместо того, чтобы отключать анимацию, мы просто ее изменяем. Однако это все еще обходной путь и довольно сложный. Я в основном ищу не идеальный обходной путь, а скорее по причине, почему именно он ведет себя именно так.