jquery append () не работает с динамически добавленными элементами - PullRequest
6 голосов
/ 04 декабря 2011

Рассмотрим 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 ]

7 голосов
/ 04 декабря 2011

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

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

Их код:

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

2 голосов
/ 04 декабря 2011

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

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

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

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

1 голос
/ 04 декабря 2011

Почему бы просто не сделать это в начальном приложении?

$('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 , показывающий два отдельных обработчика.

...