Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS-transition on elements added dynamically via JavaScript [duplicate]

I create an element with like this:

var dynamic_gallery = document.createElement("li");  

Now I assign a class to it, which gives the element style a { height:0;transition-duration:.4s; }

dynamic_gallery.className = "gallery-container";  

Right after this step, I add another class with style { height:400px !important; }

dynamic_gallery.className += " gallery-exp";

From my understanding, the element should be created invisible and immediately recieve a change in height and grow smoothly to 400px.
So why will it still appear instantly in full height?

like image 490
Moritz Friedrich Avatar asked Feb 13 '14 12:02

Moritz Friedrich


2 Answers

CSS3 transition-delay event will be fired for elements after being live. Here you have set height to 0 but still "li" element is not in DOM(so its not live).

so after assigining height to 0px make it live. ie

document.body.appendChild(dynamic_gallery)

The "li" is live now,and transition-duration:.4s event has been registered.

Now increase the height to 400px by assigning the class, dynamic_gallery.className += " gallery-exp";

You will see smooth animation.

EDIT:Most browser needs time to make element live so we need a timeout of 0 seconds to make it work.

hence it should be

setTimeout(function(){
    dyna_gallery.className += " gallery-exp";},0)

instead of

dyna_gallery.className += " gallery-exp";

Fiddle: http://jsfiddle.net/zYLmw/

like image 166
WebServer Avatar answered Nov 11 '22 06:11

WebServer


Why would it grow "smoothly" ?

All changes of the DOM (including CSS) you do in your script aren't rendered until your code ends.

If you want the change to be visible, you have to force your code to end, for example with a setTimeout :

var dynamic_gallery = document.createElement("li");
dynamic_gallery.className = "gallery-container"; 
... appending
setTimeout(function(){
    dynamic_gallery.className += " gallery-exp";
}, 2000); // wait 2 seconds before adding the class

But :

  • this won't make it smooth at all. To do this you would have to call many changes (changing the height of the elements rather than a class) instead of just one
  • using !important is almost always the mark of a bad design. Here it is.

Here's an example of animating the height of your element from 0 to 400 px :

(function grow(){
  var h = (parseInt(dynamic_gallery.style.height)||0)+1;
  dynamic_gallery.style.height = h+'px';
  if (h<400) setTimeout(grow, 30);
})();

Demonstration

like image 32
Denys Séguret Avatar answered Nov 11 '22 07:11

Denys Séguret