JQuery function after .append

How to call a function after jQuery .append ?

Here is an example:

 $("#root").append(child, function(){ // Action after append is completly done }); 

Problem. When a complex DOM structure is added, calculating the new size of the root element in the callback of the add function is incorrect. Assumptions are that the DOM is not yet fully loaded, only the first child of the added complex DOM.

+81
jquery
May 20 '11 at 7:46 am
source share
18 answers

You have many valid answers here, but none of them really tell you why it works the way it does.

In JavaScript, commands are executed one at a time, synchronously in the order in which they arrive, unless you explicitly tell them that they are asynchronous using a timeout or interval.

This means that your .append method will be executed, and nothing else (excluding any possible timeouts or intervals that may exist) will be executed until this method completes its task.

To summarize, there is no need for a callback, since .append will execute synchronously.

+66
May 20 '11 at 7:59
source share

Well, I have exactly the same problem with recalculating the size, and after frequent headaches I do not agree that .append() behaves strictly synchronously. Well, at least in Google Chrome. See the following code.

 var input = $( '<input />' ); input.append( arbitraryElement ); input.css( 'padding-left' ); 

The padding-left property loads correctly in Firefox, but in Chrome it is empty. Like all other CSS properties, I suppose. After some experimentation, I had to agree to wrap the โ€œgetterโ€ CSS in setTimeout() with a 10ms delay, which I know is UGLY, damn it, but the only one that works in Chrome. If any of you had an idea how best to solve this problem, I would be very grateful.

+19
May 30 '12 at 15:04
source share

Although Marcus Equwall is absolutely right about append synchronization, I also found that in odd situations, sometimes the DOM is not fully displayed by the browser when the next line of code runs.

In this scenario, the shadow solutions are in the right direction - using .ready - however it is much more difficult to associate the call with the original add.

 $('#root') .append(html) .ready(function () { // enter code here }); 
+14
Jul 14 '16 at 9:55
source share

I have another option that might be useful for someone:

 $('<img src="http://example.com/someresource.jpg">').load(function() { $('#login').submit(); }).appendTo("body"); 
+5
Jul 18 '13 at 5:16
source share

Using MutationObserver can act as a callback for the jQuery append method:

I explained this in another question , and this time I will only give an example for modern browsers:

 // Somewhere in your app: var observeDOM = (() => { var MutationObserver = window.MutationObserver || window.WebKitMutationObserver; return function(obj, callback){ if( MutationObserver ){ // define a new observer var obs = new MutationObserver(function(mutations, observer){ if( mutations[0].addedNodes.length || mutations[0].removedNodes.length ) callback(mutations); }); // have the observer observe foo for changes in children obs.observe( obj, { childList:true, subtree:true }); return obs; } } })(); ////////////////// // Your code: // setup the DOM observer (on the appended content parent) before appending anything observeDOM( document.body, ()=>{ // something was added/removed }).disconnect(); // don't listen to any more changes // append something $('body').append('<p>foo</p>'); 
+5
Jul 03 '16 at 16:15
source share

I ran into the same problem and found a simple solution. Add after calling the add function, the document is ready.

 $("#root").append(child); $(document).ready(function () { // Action after append is completly done }); 
+4
May 20 '16 at 9:12
source share

I think this answered well, but it is a little more specific to handling "subChild_with_SIZE" (if it comes from a parent, but you can adapt it where it can be)

 $("#root").append( $('<div />',{ 'id': 'child' }) ) .children() .last() .each(function() { $(this).append( $('<div />',{ 'id': $(this).parent().width() }) ); }); 
+3
Jan 27 2018-12-12T00:
source share

I am surprised by all the answers here ...

Try the following:

 window.setTimeout(function() { /* your stuff */ }, 0); 

Pay attention to the timeout 0. This is not an arbitrary number ... as I understand it (although my understanding can be a little shaky), there are two javascript event queues - one for macros and one for micro-events. In the "larger" district zone, tasks are stored that update the user interface (and the DOM), while the micro-queue performs operations such as a quick task.

Also, understand that setting a timeout does not guarantee that the code is executing that particular value. What this does is essentially put the function in the highest order (the one that processes the UI / DOM), and does not start it until the specified time.

This means that setting a timeout of 0 places it in the UI / DOM part of the javascript event queue, which will be executed with the next possible probability.

This means that the DOM is updated with all the previous elements of the queue (for example, inserted via $.append(...); and when your code works, the DOM is fully accessible.

(ps - I found out about this from the "Secrets of the JavaScript Ninja" - a great book: https://www.manning.com/books/secrets-of-the-javascript-ninja )

+3
Jan 27 '17 at 12:02 on
source share

$.when($('#root').append(child)).then(anotherMethod());

+2
Feb 10 '12 at 12:05
source share

The jquery append function returns a jQuery object, so you can just tag the method at the end

 $("#root").append(child).anotherJqueryMethod(); 
0
May 20 '11 at 7:49 am
source share

For images and other sources, you can use this:

 $(el).one('load', function(){ // completed }).each(function() { if (this.complete) $(this).load(); }); 
0
Feb 09 '16 at 4:18
source share

I know this is not the best solution, but best practice:

 $("#root").append(child); setTimeout(function(){ // Action after append },100); 
-one
Oct 28 '13 at 21:43
source share

I ran into this problem when coding HTML5 for mobile. Some browser / device combinations caused errors because the .append () method did not immediately reflect changes in the DOM (which caused JS to crash).

The quick and dirty solution for this situation was:

 var appint = setInterval(function(){ if ( $('#foobar').length > 0 ) { //now you can be sure append is ready //$('#foobar').remove(); if elem is just for checking //clearInterval(appint) } }, 100); $(body).append('<div>...</div><div id="foobar"></div>'); 
-one
Mar 17 '14 at 12:45
source share

Yes, you can add a callback function to any DOM insert:
$myDiv.append( function(index_myDiv, HTML_myDiv){ //.... return child })

Check out the jQuery documentation: http://api.jquery.com/append/
And here's a practical, similar example: http://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_html_prepend_func

-one
Mar 24 '14 at 13:09
source share

I recently encountered a similar problem. The solution for me was to recreate the collection. Let me try to demonstrate:

 var $element = $(selector); $element.append(content); // This Doesn't work, because $element still contains old structure: $element.fooBar(); // This should work: the collection is re-created with the new content: $(selector).fooBar(); 

Hope this helps!

-one
Mar 29 '14 at 23:46
source share

In jquery you can use right after adding

 $(function(){ //code that needs to be executed when DOM is ready, after manipulation }); 

$ () calls a function that either registers a callback ready for the DOM (if the function is passed to it), or returns elements from the DOM (if the selector string or element is passed to it)

You can find more here.
difference between $ and $ () in jQuery
http://api.jquery.com/ready/

-one
Sep 12 '18 at 23:56 on
source share
 $('#root').append(child); // do your work here 

Append has no callbacks, and this is code that runs synchronously - there is no risk that it will NOT execute

-3
May 20 '11 at 7:51
source share
 $('#root').append(child).anotherMethod(); 
-four
May 20 '11 at 7:54 am
source share



All Articles