Я бы проголосовал за причуду или разницу в реализации.
До переходов действительно не имело значения, какие стили порядка были применены, потому что на практике порядок не имел значения, только специфичность.Но с переходами, элемент задержки был добавлен в стили, что является сутью проблемы.
Не зная, как какой-либо из браузеров применяет стили, я могу предположить, что Safari и Chrome проводят некоторые оптимизации, чтобы не приходилось перетекать страницу после каждого обновления стиля.Вместо этого они, вероятно, ожидают обновления определенных интервалов или событий, например, в конце блоков кода.
Некоторые различия подробно описаны здесь:
http://taligarsiel.com/Projects/howbrowserswork1.htm
Хотя, я не знаю, покрыта ли эта конкретная проблема.
В качестве демонстрации , другой способ решить эту проблему - это иметь 2 обработчика щелчков:
$('button#nodelay').on('click', function() {
var $el = $('#square');
$el.removeClass('csstransition');
$el.css('left', '100px');
}).on('click', function() {
$el.addClass('csstransition');
});
Это в основном разделяет два обновления на отдельные блоки кода, во многом как метод setTimeout
.
Кроме того, поскольку переходы все еще являются черновым стандартом, я не буду зависеть от того, будет ли это поведение согласованным, иЕсть причуды.(Я столкнулся с проблемой, когда переход left
и top
одновременно не работал во всех браузерах).
Редактировать
Для дальнейшего объяснения, если браузер отображает весь CSS, как только он добавляется в DOM, вы получаете этот поток:
- CSS
left: 300px
добавляется к элементу DOM - Отображаемый стиль: браузер проверяет напосмотрим, есть ли переход на элемент.Если так, оживите, если нет, примените немедленно.В этом случае не является переходом (пока), поэтому анимация не выполняется.
- CSS
transition: left 2s ease-out
добавлено к элементу DOM - Стиль визуализации: без изменения рендерингапереход применяется к будущим
left
изменениям.
Однако, если браузер оптимизирует рендеринг CSS, сгруппировав в конце блоки кода (или что-то в этом роде), вы получите следующее:
- CSS
left: 300px
добавлен к элементу DOM - CSS
transition: left 2s ease-out
добавлен к элементу DOM - Достигнута точка рендеринга (конец блока кода и т. Д.), Всеотображаемые стили:
- Когда применяется
left
, браузер проверяет, есть ли переход к элементу.Если так, оживите, если нет, примените немедленно.В этом случае - это переход, поэтому происходит анимация.
Итак, длина анимации и время ожидания не имеют значения.Важно то, что left: 300px
отображается до перехода применяется.В настоящее время в WebKit это означает применение стиля transition
в отдельном, более позднем кодовом блоке, чем стиль left
.Это достигается всеми предлагаемыми ответами setTimeout
(событие с задержкой 0), отдельным обработчиком щелчка (если применяется секунда) или обратным вызовом функции.
Вот еще один способ, который работает:
$('button#nodelay').on('click', function() {
var $el = $('#square');
$el.removeClass('csstransition');
$el.css('left', '100px').css('left'); // <-- This (or .show() even)
$el.addClass('csstransition');
});
Это работает, потому что вы заставляете браузер останавливать и оценивать CSS, чтобы вы могли получить значение left
(хотя вы можете поместить любой действительный атрибут css во второй вызов .css()
).В этом случае он применяет весь CSS и заставляет элемент (-ы) выполнить повторную визуализацию.