Jquery append () does not work with dynamically added elements

Consider HTML

<ul> <li>Default item</li> <li>Default item</li> </ul> <button>Append</button> 

and jQuery code

 $('button').live('click', function(){ //This action is done by an external script. $('ul').append('<li>Added item</li>'); }); $('ul li').append('<b> x</b>'); // This action is done by me 

The thing is, I need to add the "x" sign to all newly added elements in dom.

In this case, only items by default are added with an “x” mark.

Newly added items are not added with "x".

I am sure that the work will be simple, but it will not work out correctly.

Real-time example - http://jsfiddle.net/vaakash/LxJ6f/1/

+6
source share
3 answers

Your code works immediately, and therefore, of course, it has access only to existing elements. Code that adds new list items starts later when the user clicks something. You will also have to connect to this process.

One way is to bind the same event and run the code from the event handler. Be sure to pin the event after .

Their code is:

 $('button').live('click', function(){ $('ul').append('<li>Added item</li>'); }); 

Your code ( after ):

 $('button').live('click', markButtons); markButtons(); function markButtons() { $('ul li:not(.marked)') .addClass("marked") .append('<b> x</b>'); } 

Updated fiddle

The reason I said that your code must complete its binding after their code is because jQuery guarantees the order of calls to event handlers. When an event occurs, handlers are called in the order in which they were attached. By attaching your handler after they join them, you guarantee that your handler will be called after they do their thing.

If you are worried that the order is messy, you can always put your code a bit back:

 $('button').live('click', function() { setTimeout(markButtons, 0); }); 

This way your code will work after all the event handlers connected to click are started.

+6
source

You must repeat the code "x" in the event handler:

 $('button').live('click', function(){ //This action is done by an external script. $('ul').append( $('<li>Added item</li>').append('<b>x</b>') ); }); 

Of course, you could just put the bold "x" on the right in the <li> when you add it ...

edit If you cannot change the click handler, then the only thing you can do is either query the DOM or try something like what @TJ Crowder offers (which I think should work fine).

+2
source

Why not just do it in the original application?

 $('button').live('click', function(){ //This action is done by an external script. $('ul').append('<li>Added item<b> x</b></li>'); }); 

Since it seems that you do not have access to the script that is performing the addition, you can link your own handler.

 $('button').live('click', function(){ //This action is done by an external script. setTimeout(function() { $('ul li:not(li:has(b))').append('<b> x</b>'); }, 10); }); 

This will select li elements that currently do not have a nested element b , and it will add it.

I put it in setTimeout , since you cannot guarantee the execution order of the handlers.

If you prefer the right CSS selector, do this instead:

 $('ul li').not($('li b').closest('li')).append('<b> x</b>'); 

or that:

 $('ul li').not(function() { return $(this).find('b').length; }).append('<b> x</b>'); 

JSFIDDLE DEMO showing two separate handlers.

+1
source

Source: https://habr.com/ru/post/903050/


All Articles