Я хочу добавить в приложение немного анимации, анимацию решил реализовывать при помощи css3. И у меня возникли проблемы с этим.
Сначала я опишу алгоритм работы анимации:
Есть некая кнопка по которой при клике плавно выезжает менюшка. При этом менюшка динамическая, она каждый раз заново генерируется и вставляется в DOM
Вот простой код, который по логике уже должен работать:
<html>
<head>
<style type="text/css">
.menu {
width: 0px;
height: 20px;
text-align: center;
color: #fff;
background-color: green;
}
.animate {
width: 400px;
transition: width 2s;
}
</style>
</head>
<body>
<script type="text/javascript">
div = document.createElement('div');
div.innerHTML = 'Dynamic Menu'
div.className = 'menu';
document.body.appendChild( div );
div.className += ' animate';
</script>
</body>
</html>
, но если запустить код то никакой анимации не произойдет, хотя она и прописана в стилях -
transition: width 2s;
Проблема в том что современные браузеры оптимизируют работу с DOM, и они стараются произвести максимум работы с элементом перед вставкой его в DOM. Поэтому если посмотреть в код на строки
25 и
27 становится ясно что они выполняются не в той последовательности как записаны. Тоесть браузер сначала добавляет класс
animate в котором описана анимация а после вставляет элемент в страницу и естественно никакой анимации не происходит.
Чтоб проверить это нужно вынести добавление класса
animate в асинхронную функцию, например вот так:
setTimeout( function () {
div.className += ' animate';
}, 10 );
<html>
<head>
<style type="text/css">
.menu {
width: 0px;
height: 20px;
text-align: center;
color: #fff;
background-color: green;
}
.animate {
width: 400px;
transition: width 2s;
}
</style>
</head>
<body>
<script type="text/javascript">
div = document.createElement('div');
div.innerHTML = 'Dynamic Menu'
div.className = 'menu';
document.body.appendChild( div );
setTimeout( function () {
div.className += ' animate';
}, 10 );
</script>
</body>
</html>
, ну вот все работает.
Но так как предполагается достаточно много анимированных элементов, то совсем не хочется иметь великое множество
setTimeout в проекте.
Ну и вопрос:
как установить класс новосозданному элементу, гарантированно после вставки этого элемента в DOM? ( Не используя setTimeout, setInterval и пр. )