Когда вы объявляете стиль кнопки как transition: all 0.15s;
, это также влияет на свойство top
. Следовательно, в вашем потоке:
- Верхняя анимация действительно происходит через несколько мс после манипуляции css
- Каждый шаг верхней анимации подвергается переходу
Из-за первого, уже есть гоночное состояние, которое может привести к тому, что верхняя анимация останется go незамеченной, но из-за второго также есть замедление на каждом этапе анимации jQuery.
Если не указано, $. Fn.animate Функция замедления по умолчанию имеет значение swing
, которое определяется как:
function( p ) {
return 0.5 - Math.cos( p * Math.PI ) / 2;
}
Где p
находится между 0 и 1.
В этом случае вы просите jQuery изменить top
с 0 на -100 за 150 мс. Обычно интервал анимации составляет около 13 мс , но, скажем, это ровно 15 мс, поэтому мы имеем 10 шагов анимации . Из-за замедления swing
, первый шаг составляет:
100 * (0.5 - Math.cos( (0.1 * Math.PI ) / 2) = 2.45
Другими словами, из-за transition: all 0.15s
и оставления условия гонки отдельно, нажатие кнопки будет масштабировать его горизонтально до 0 и переместите его на 2,45 пикселя вверх за 0,15 с .
Если вместо этого вы только передадите свойство transform
и оставите переход top
на jQuery, вы увидите они происходят параллельно.
В следующем фрагменте я замедлил процесс до 1 с, добавил операторы консоли на каждом шаге и включил обычную кнопку, еще одну, которая только переходит transform
, и третью, которая переходит transform
и top
, которые не используют jQuery анимации.
// find elements
var button = $("button.animate");
// handle click
button.on("click", function() {
console.clear();
$(this).css(
"transform", (index, value) => {
console.log(`top: transform was ${value}`);
return "scaleX(0)";
}
);
console.log('before $.fn.animate');
$(this).animate({
"top": "-100px"
}, 1000, 'swing', () => {
console.log('finish animation');
window.setTimeout(() => {
console.log('restore initial state')
$(this).css({
transform: "unset",
top: 0
});
}, 2000);
});
});
// handle click
$("button.no_animate").on("click", function() {
console.clear();
$(this).css({
"transform": "scaleX(0)",
"top": "-100px"
});
window.setTimeout(() => {
console.log('restore everything');
$(this).css({
transform: "unset",
top: 0
});
}, 2000);
});
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
p {
color: white;
}
button {
background: #0084ff;
border: none;
border-radius: 5px;
padding: 8px 14px;
font-size: 15px;
color: #fff;
position: relative;
}
button.animate.all {
transition: all 1s;
}
button.animate.transform {
transition: transform 1s;
}
button.no_animate {
top: 0;
transition: top 1s, transform 1s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<p id="check">Hello World</p>
<button class="animate all">I Transition all</button>
<button class="animate transform">I Transition "transform" </button>
<button class="no_animate transform">I don't use animate </button>
</div>