javascript - Clean way to programmatically use CSS transitions from JS? -


as title implies, there proper way set initial css properties (or class) , tell browser transition these value?

for example (fiddle):

var el = document.queryselector('div'),     st = el.style; st.opacity = 0; st.transition = 'opacity 2s'; st.opacity = 1; 

this not animate opacity of element in chrome 29/firefox 23. because (source):

[...] you’ll find if apply both sets of properties, 1 after other, browser tries optimize property changes, ignoring initial properties , preventing transition. behind scenes, browsers batch property changes before painting which, while speeding rendering, can have adverse affects.

the solution force redraw between applying 2 sets of properties. simple method of doing accessing dom element’s offsetheight property [...]

in fact, hack work in current chrome/firefox versions. updated code (fiddle - click run after opening fiddle run animation again):

var el = document.queryselector('div'),     st = el.style; st.opacity = 0; el.offsetheight; //force redraw st.transition = 'opacity 2s'; st.opacity = 1; 

however, rather hackish , reported not work on android devices.

another answer suggests using settimeout browser has time perform redraw, fails in don't know how long take redraw take place. guessing decent number of milliseconds (30-100?) ensure redraw occurred means sacrificing performance, unnecessarily idling in hopes browser performs magic in little while.

through testing, i've found yet solution has been working great on latest chrome, using requestanimationframe (fiddle):

var el = document.queryselector('div'),     st = el.style; st.opacity = 0; requestanimationframe(function() {     st.transition = 'opacity 2s';     st.opacity = 1; }); 

i assume requestanimationframe waits until right before beginning of next repaint before executing callback, hence browser not batch property changes. not entirely sure here, works nicely on chrome 29.

update: after further testing, requestanimationframe method not work on firefox 23 - seems fail of time. (fiddle)

is there proper or recommended (cross-browser) way of achieving this?

there isn't clean way @ moment (without using css animations -- see the nearby answer james dinsdale example using css animations). there spec bug 14617, didn't receive traction since 2011.

settimeout not work reliably in firefox (this design).

i'm not sure requestanimationframe -- edit original question says doesn't work reliably either, did not investigate. (update: looks requestanimationframe is considered @ least 1 firefox core developer place can make more changes, not see effect of previous changes.)

forcing reflow (e.g. accessing offsetheight) possible solution, transitions work should enough force restyle (i.e. getcomputedstyle): https://timtaubert.de/blog/2012/09/css-transitions-for-dynamically-created-dom-elements/

window.getcomputedstyle(elem).opacity; 

note running getcomputedstyle(elem) not enough, since it's computed lazily. believe doesn't matter property ask getcomputedstyle, restyle still happen. note asking geometry-related properties still might cause more expensive reflow.

more information on reflow/restyle/repaint: http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/


Comments

Popular posts from this blog

linux - Does gcc have any options to add version info in ELF binary file? -

android - send complex objects as post php java -