Вы сталкиваетесь с изменением перехода , которое не работает, если скрывается элемент , но непосредственно в свойстве transition
.
Вы можете обратитесь к этому ответу , чтобы понять, как CSSOM и DOM связаны для процесса "перерисовки".
По сути, браузеры обычно ждут следующего кадра рисования , чтобы пересчитать все новые позиции в ящиках и, следовательно, для применения правил CSS к CSSOM.
Так что в вашем обработчике Promise, когда вы сбрасываете transition
в ""
, transform: ""
еще не был вычислен , Когда он будет рассчитан, transition
уже будет сброшен на ""
, и CSSOM запустит переход для обновления преобразования.
Однако мы можем заставить браузер вызвать «reflow» и, таким образом, мы можем сделать так, чтобы он пересчитал положение вашего элемента, прежде чем сбросить переход на ""
.
const box = document.querySelector('.box')
box.addEventListener('click', e => {
if (!box.style.transform) {
box.style.transform = 'translateX(100px)'
new Promise(resolve => {
setTimeout(() => {
box.style.transition = 'none'
box.style.transform = ''
box.offsetWidth; // this triggers a reflow
resolve('Transition complete')
}, 2000)
}).then(() => {
box.style.transition = ''
})
}
})
.box {
width: 100px;
height: 100px;
border-radius: 5px;
background-color: #121212;
transition: all 2s ease;
}
<div class = "box"></div>
Что делает использование Обещания совершенно ненужным:
const box = document.querySelector('.box')
box.addEventListener('click', e => {
if (!box.style.transform) {
box.style.transform = 'translateX(100px)'
setTimeout(() => {
box.style.transition = 'none'
box.style.transform = ''
box.offsetWidth; // this triggers a reflow
// even synchronously
box.style.transition = ''
}, 2000)
}
})
.box {
width: 100px;
height: 100px;
border-radius: 5px;
background-color: #121212;
transition: all 2s ease;
}
<div class = "box"></div>
И для объяснения микро-задач, таких как Promise.resolve()
или MutationEvents или queueMicrotask()
, вы должны понимать, что они будут запущены, как только будет выполнено текущее задание, 7-й шаг модели обработки Event-l oop , перед этапами рендеринга .
Так что в вашем случае это очень похоже на синхронный запуск.
Кстати, остерегайтесь микро-задач, они могут быть блокированы на некоторое время. L oop:
// this will freeze your page just like a while(1) loop
const makeProm = ()=> Promise.resolve().then( makeProm );