jQuery append() не работает с динамически добавляемыми элементами

рассмотрим HTML

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

и код jQuery

$('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

дело в том, что мне нужно добавить знак "x" ко всем недавно добавленным элементам в dom.

в этом случае только элементы по умолчанию добавляются с меткой "x".

вновь добавленные элементы не добавляются "x".

Я уверен, что работа будет простой, но не могу получить это право !!

живой пример - http://jsfiddle.net/vaakash/LxJ6f/1/

3 ответов


ваш код запускается сразу, и поэтому, конечно, он имеет доступ только к элементам, которые уже существуют. Код, добавляющий новые элементы списка, запускается позже, когда пользователь щелкает что-то. Вам придется подключиться к этому процессу.

один из способов-подключить одно и то же событие и запустить код из обработчика событий. Обязательно зацепите событие после они делают.

код:

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

ваш код (после их):

$('button').live('click', markButtons);

markButtons();

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

обновленный скрипку

причина, по которой я сказал, что ваш код должен сделать его подключение после их код, что jQuery гарантирует порядок вызовов обработчиков событий: когда происходит событие, обработчики вызываются в том порядке, в котором они были прикреплены. Прикрепляя свой обработчик после того, как они прикрепляют свои, вы гарантируете, что ваш обработчик вызывается после того, как они сделали свое дело.

если вы беспокоитесь о порядок перепутался, вы всегда можете немного задержать свой код:

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

таким образом, ваш код гарантированно запускается после всех обработчиков событий, подключенных к click были выполнены.


вы должны повторить код " x " в обработчике событий:

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

конечно, можно просто поставить жирный "х" в <li> когда вы добавляете его ...

редактировать если вы не можете изменить обработчик щелчка, то единственное, что вы можете сделать, это либо опросить DOM, либо попробовать что-то вроде того, что предлагает @T. J. Crowder (что, я думаю, должно работать нормально).


почему бы просто не сделать это в начальной строкой?

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

поскольку похоже, что у вас нет доступа к скрипту, который делает добавление, вы можете связать свой собственный обработчик.

$('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);
});

это позволит выбрать li элементы, которые в настоящее время не имеют вложенную b элемент, и он добавит один.

Я setTimeout поскольку вы не можете быть в состоянии гарантировать порядок выполнения обработчиков.

если вы предпочитаете допустимые селекторы CSS, сделайте это вместо этого:

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

или такой:

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

JSFIDDLE DEMO показаны два отдельных обработчика.