Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 23.06.2013, 13:38
Аватар для Magneto
Люмус, Емаксос Developer!
Отправить личное сообщение для Magneto Посмотреть профиль Найти все сообщения от Magneto
 
Регистрация: 06.05.2010
Сообщений: 677

CSS3 анимация (transition)
Я хочу добавить в приложение немного анимации, анимацию решил реализовывать при помощи 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 и пр. )
Ответить с цитированием
  #2 (permalink)  
Старый 23.06.2013, 14:21
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Ты почти отгадал, в чём соль

Opera reflow bug

можно просто вызвать forced отрисовку.

я это делал так :

window.scrollBy(0, 0);


ну или можно подождать отрисовки и тогда применять стиль - это делается с помощью requestAnimationFrame, который вызывает callback перед отрисовкой. Двойной вызов rAF сделает бочку.

Удачи!) переходы (transitions) вообще такая муть .... зря с ними связываться только
Ответить с цитированием
  #3 (permalink)  
Старый 23.06.2013, 15:05
без статуса
Отправить личное сообщение для Deff Посмотреть профиль Найти все сообщения от Deff
 
Регистрация: 25.05.2012
Сообщений: 8,219

Вариант:
<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');
function btnClk(){
		div.innerHTML = 'Dynamic Menu'
		div.className = 'menu';
		document.body.appendChild( div );

}
function btnClk2(){
		div.className=div.className.replace(/ ?animate/i,'')+' animate';

}
	</script>
<input type=button value=Клик onmousedown="btnClk()" onmouseup="btnClk2()">
</body>
</html>
Ответить с цитированием
  #4 (permalink)  
Старый 23.06.2013, 17:37
Аватар для Magneto
Люмус, Емаксос Developer!
Отправить личное сообщение для Magneto Посмотреть профиль Найти все сообщения от Magneto
 
Регистрация: 06.05.2010
Сообщений: 677

Сообщение от melky
можно просто вызвать forced отрисовку.
Спасибо, я остановил свой выбор на:
div.offsetTop

, это работает в: Chrome 27, Firefox 21, Opera 12.15 и IE 10.

Сообщение от Deff
Вариант: ...
Спасибо, хороший вариант, но мне он не подошел.
Я пишу на Backbone.js и Chaplin.js, и там событие которое вызывает меню кастомное да и вообще там все так "православно" )). Ну и есть более легкий способ, см. выше.
Ответить с цитированием
  #5 (permalink)  
Старый 19.12.2014, 11:39
Новичок на форуме
Отправить личное сообщение для maxycws Посмотреть профиль Найти все сообщения от maxycws
 
Регистрация: 19.12.2014
Сообщений: 6

Сделал перевод статьи по анимациям для начинающих. От и до расписано что для чего. Живые примеры тут же в тексте. Можно копировать и вставлять сразу к себе на сайт.

http://devdocs.ru/verstka/css3-anima...for-beginners/
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Анимация в real-time приложениях(Нужны советы) ak-o AJAX и COMET 5 05.04.2013 11:34
Не работает анимация при загрузки ajax ArtOs Общие вопросы Javascript 0 24.05.2012 17:52
CSS3 3 примера flash и сss3 mycoding Оффтопик 4 25.07.2010 15:15
Анимация. Помогите понять почему не работает. kadurban jQuery 4 08.07.2010 20:50
Цикличность анимация? SashaBorandi jQuery 1 25.12.2008 09:20