Await appendChild для переходов CSS

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

let DOM = document.createElement('div');

DOM.classList.add('box');

document.body.appendChild(DOM);

DOM.classList.add('purple');
.box {
  width: 100px;
  height: 100px;
  
  background-color: blue;
 
  transition: background-color 0.25s;
}

.box.purple {
  background-color: purple;
}

let DOM = document.createElement('div');

DOM.classList.add('box');

document.body.appendChild(DOM);

window.setTimeout(() => {
  DOM.classList.add('purple');
}, 100);
.box {
  width: 100px;
  height: 100px;
  
  background-color: blue;
 
  transition: background-color 0.25s;
}

.box.purple {
  background-color: purple;
}

Тайм-аут кажется чем-то вроде хакерского решения, которое может дать сбой, если машина была медленной, или вызвать чрезмерную задержку на более быстрых машинах. Но в первую очередь я ищу лучшее решение этой проблемы. Есть ли способ к awaitappendChild, чтобы класс добавлялся сразу после добавления элемента?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
28
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Фактически здесь подойдет любое значение задержки. Даже это работает:

window.setTimeout(() => {
    DOM.classList.add('purple');
}, 0);

jsfiddle: https://jsfiddle.net/OscarSaharoy/x46wnehs/1/

Это из-за цикла событий браузера. Выполняется весь нормальный код, затем выполняются его эффекты, затем выполняются любые функции setTimout. Таким образом, без setTimeout вокруг вызова classList.add коробка добавляется с его background-color уже фиолетовым. Но с setTimout коробка добавляется, а затем меняется ее background-color, вызывая плавный переход.

Лучшим решением может быть использование ключевых кадров css, см. Здесь реализацию, использующую их: https://codepen.io/ericwshea/pen/EyzZQg

Таким образом, вы можете указать в css что-то вроде animation: color-change 0.25s; для элемента, который вы добавляете, а также

@keyframes color-change {
    from {
        background-color: blue;
    }
    to {
        background-color: purple;
    }
}

в теле css.

Спасибо, это здорово. Я знаю способ анимации. В этой ситуации я полагаю, что многие функции зависят от поведения перехода, и это всего лишь крайний случай. На мой взгляд, имеет смысл просто использовать этот метод, а не поддерживать анимацию вместе с переходом.

Jack 04.04.2021 05:13

Ага для меня имеет смысл :)

Oscar Saharoy 04.04.2021 09:51

Попробуйте "загрузить". здесь работает. Я только добавил лишний CSS b / c, мне больше нечего было делать.

let DOM = document.createElement('div');

DOM.classList.add('box');

document.body.appendChild(DOM);

onload = ()=>DOM.classList.add('purple');
.box {
  width: 100px;
  height: 100px;
  margin: 50px 0px 0px 50px;
  
  background-color: blue;
 
  transition: all 10s cubic-bezier(0.3, 5, 0.5, -2);
}

.box.purple {
  background-color: purple;
  width: 200px;
  height: 200px;
  margin: 0px;
  transform: rotate(1080deg);
}

Спасибо за этот ответ. Не могу поверить, что не подумал об этом, все так просто.

Jack 07.04.2021 03:43

Другие вопросы по теме