Javascript-форум (https://javascript.ru/forum/)
-   Opera, Safari и др. (https://javascript.ru/forum/css-html-browser/)
-   -   Opera reflow bug (https://javascript.ru/forum/css-html-browser/25227-opera-reflow-bug.html)

melky 29.01.2012 15:44

Opera reflow bug
 
описание симптомов :

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

получается, что элемент не анимируется, а к нему применяется конечный стиль сразу.

Опытным путем выяснил, что задержка перед присваиванием конечного стиля в 1000мсек помогает. в 1, 10 и 100 мсек не помогает.

В связи с этим, у меня следующий вопрос : как отловить в опере событие перерисовки страницы? или как в ней назначить стиль элементу после перерисовки ?

melky 29.01.2012 22:34

UP'аю тему. неужели никто не знает? гугл мне не помог.

Octane 29.01.2012 23:24

а событие transitionsend поддерживается?
----------------
гугл говорит OTransitionEnd

Pavel M. 29.01.2012 23:34

не пойму о чем речь идет?
попробовал в опере пример с сайта mdn
http://jsfiddle.net/RwtHn/5/ хорошо работает
опера 11.61

melky 30.01.2012 13:02

Цитата:

Сообщение от Octane (Сообщение 154031)
а событие transitionsend поддерживается?
----------------
гугл говорит OTransitionEnd

в том дело, что оно не успевает сработать, т.к. конечный стиль стиль применяется до перерисовки.

Цитата:

Сообщение от Pavel M. (Сообщение 154032)
не пойму о чем речь идет?
попробовал в опере пример с сайта mdn
http://jsfiddle.net/RwtHn/5/ хорошо работает
опера 11.61

тоже. но это не то совсем. делается переход с помощью JS. полностью. без наводок мыши и кликов.

без примеров кода будет непонятно.

смотрите : пример № 1. стиль применяется сразу, как стал доступен элемент.

работает только в хроме (!). в мозилле, как и в опере, не успевает.

попробуем поставить таймаут, чтобы применить конечный стиль после перерисовки. пример № 2. теперь работает и в FF - таймаут помог применить конечные свойства стиля после перерисовки.

конечно, таймаут - гнилое дело. лёгким движением руки он заменяется на requestAnimationFrame : пример № 3.

но это не работает в опере.

в интернете есть замена этой функции другой, с таймаутом :
function( callback ){                 
     window.setTimeout(callback, 1000 / 60);  // 1000/60 == 16.6
};

код взят отсюда

попробуем использовать его. пример № 4. и о чудо, он работает в опере!

т.к. меня не интересует то, что стили применены изначально ( в <style> и прописаны человеком ), я введу генерацию стиля. пример № 5. для удобства проверки сгенерированные правила выводятся в консоль.

для оперы (из-за которой сыр-бор) генерируется такой CSS :
border-radius:50px;
width:50px;
height:50px;
background-color:#c00;
position:absolute;
top:0;
left:0;
*!*
-o-transition:all 1s;
*/!*


и в ней наконец-то всё хорошо! но есть одно "НО" : в FF если открыть последний пример, то скрипт опять применяет стиль до перерисовки. если запустить скрипт, уже открыв ссылку (Click to view), то всё хорошо. но если нажать F5, то при загрузке шарик не анимируется, а уже висит по середине страницы.

в это же время, в опере и хроме всё хорошо!

и ещё одно "НО"... для requestAnimationFrame для оперы ставится таймаут в 16 мсек. в своём скрипте (не в этом) я ставил таймаут в 1мсек - не помогало. Ставил 10мсек - тоже не анимируется. Даже 100мсек не помогало!
И только задержка в одну секунду (!) помогла опере применить transition к элементу и после назначения конечных css-правил таки проанимировать их изменение.

Чувствуете разницу ? 1000/60 и 1000.

Нужно как-то определить момент перерисовки в опере. Пытаться предугадать его с помощью таймаута - гнилое дело.

Pavel M. 30.01.2012 15:07

даже пример №1, если запускать скрипт не сразу а по загрузке DOM у меня выполнился в Opere и FF
http://javascript.info/play/BdI6cc

использовал jQuery, так как кроссбраузерная функция длинная

возможно и в других примерах стоит скрипт меняющий css у красного кружка запускать по DOM ready ?

melky 30.01.2012 15:08

Цитата:

Сообщение от Pavel M. (Сообщение 154123)
даже пример №1, если запускать скрипт не сразу а по загрузке DOM у меня выполнился в Opere и FF
http://javascript.info/play/BdI6cc

использовал jQuery, так как кроссбраузерная функция длинная

возможно и в других примерах стоит скрипт меняющий css у красного кружка запускать по DOM ready ?

Pavel M. , загрузка дерева не гарантирует того, что стили применятся на разных отрисовках. Я включил ещё 2 браузера в фоне, музыку и киношку и нажал на Ctrl+F5 (обновить страницу без кеша). Потом попробовал F5 - обновит страницу с учётом кеша. В файрфоксе 2 из 3 раз шарик не анимировался. В опере это решило проблему, но как мне кажется, не для пользователей на слабых машинах.

----------------------------------------------------------

В общем, я нашёл решение для Оперы и Файрфокса! Дело было вовсе и не в обработке события перерисовки (его только FF умеет обрабатывать).

Короче говоря, я решил багу с помощью корявой проверки по requestAnimationFrame (для оперы - просто по таймауту). Там я в функции проверял с помощью закешированного в переменной вычисленного стиля (computedStyle) элемента, не применились ли к нему правила из таблицы стилей ?

В общих чертах, код выглядит как-то так :
  1. вычислить префикс правил для браузера.
  2. в таблицу стилей добавить начальные свойства, а так же правило перехода (transition)
  3. в переменной сохранить вычисленный стиль элемента
  4. по какому-то интервалу проверять, применилось ли к нему хотя бы одно правило из добавленных в шаге № 2.
  5. если хотя бы одно уже применилось - добавляем в таблицу стилей новое правило с конечным стилем.
добавил комментов в коду.. пример сделал в примерочной.

Pavel M. 01.02.2012 11:43

вопрос по trasition
попробовал на горизонтальном скроллере картинок вместо js анимации
использовать transition, но кроме усложнения скрипта не заметил особых преимуществ. Визуально плавность прокрутки не возросла.

сейчас думаю, стоит игра свеч или transition лучше оставить для необязательных эффектов, которые полностью можно описать в css - там пока этой технологии место?

melky 01.02.2012 11:56

Цитата:

Сообщение от Pavel M. (Сообщение 154484)
вопрос по trasition
попробовал на горизонтальном скроллере картинок вместо js анимации
использовать transition, но кроме усложнения скрипта не заметил особых преимуществ. Визуально плавность прокрутки не возросла.

сейчас думаю, стоит игра свеч или transition лучше оставить для необязательных эффектов, которые полностью можно описать в css - там пока этой технологии место?

На одном-двух элементах этого заметно не будет. Вот, посмотрите, здесь анимируют много элементов, сначала через transitions, далее через $.animate. В хроме я вижу разницу.


PS ссылка взята из этой статьи

Pavel M. 01.02.2012 12:07

спасибо, наглядный пример


Часовой пояс GMT +3, время: 20:44.