web analytics
Contact me 
Orange D inside a circle

JQuery append into heavy loaded DOM trees

2014-04-14 06:30

Describe odd behaviour when you append DOM element into heavy loaded DOM tree

Last week we have found an odd behaviour in some website that drove us crazy for a while. The bug was related with the append of jQuery that is used to insert content to the end of the matched elements and the height method used to get the computed height of an element. Look at this code:

//divSong is created with jQuery, added to the (DOM) in the next line
$('.song-list .songs').append(divSong);
currentPlaying.css('height', divSong.height());

This piece of code normally works without any problem, or should work, because In our case randomly the computed height of the dynamic div (divSong) returns 0px. It seems like the append sometimes behave asynchronously, so when we ask for the divs height it is still 0px due to the fact that it hasn't been added to the DOM tree yet. To test this we code the following workaround:

//divSong is a div created using jQuery added to the DOM in the next line
$('.song-list .songs').append(divSong);
// Although JS is single thread, setTimeout lets the browser re-render the page after running the 
// height code.
setTimeout(function(){
    currentPlaying.css('height', divSong.height());
}, 0);

Because in Vairix we have an “always look for evidence" culture we made a search looking for something that supports (or not) this theory. We have found that many people reports similar situations, although most of them were related with other problems like asynchronous ajax callbacks or other environmental errors. Besides those false positive results, we found two questions in StackOverflow (link1, link2) that describe the same situation that we have. Both answers lead to the same solution as we had found (we rocks!).

Remember: this solutions works, but it is not due to the fact of running in a different thread (JavaScript runs in a single thread); it is because setTimeout let the browser continue with the next execution block in the queue that is the html render one.

Acknowledgments

This post was written for Vairix Software Development, so I want say thanks to them for let me share this with you in my homepage.


Significant Revisions

Apr 14, 2014: Original Publication on vairix.com and dariomac.com