Селектор jQuery не обновляется после динамического добавления новых элементов - PullRequest
14 голосов
/ 19 февраля 2012

Мой селектор:

$('section#attendance input:last')

Однако я добавляю еще один вход в раздел # посещаемость. Я хочу, чтобы селектор теперь выделил этот элемент (как и должно быть из-за :last. Однако по какой-то причине этого не происходит, и я не слишком уверен, почему?

Вот мой полный код:

$('section#attendance input:last').keydown(function(e) {
        if (e.which == 9)
        {
            var $this = $(this);
            var num = parseInt($this.attr('name').match(/\d+(,\d+)?/)[0]) + 1;
            $this.parent().append('<input type="text" name="attendance[' + num +']" value="Name and Position" class="medium" />');
        }
    });

Новый код:

    $("section#attendance").on("keydown", "input:last", function(e) {
    if (e.which == 9) {
        var $this = $(this);
        var num = parseInt($this.attr('name').match(/\d+(,\d+)?/)[0]) + 1;
        $this.after('<input type="text" name="attendance[' + num +']" value="Name and Position" class="medium" />');
    }
});

РЕДАКТИРОВАТЬ: Кажется, проблема заключается в 'input: last', так как он работает, если я просто использую input. Также, если я добавлю класс 'last' к последнему элементу, он будет работать, когда я использую 'input.last' в качестве селектора.

Ответы [ 4 ]

11 голосов
/ 19 февраля 2012

В зависимости от того, какую версию jQuery вы используете, вы должны использовать либо .delegate() (до jQuery 1.7), либо .on() (jQuery 1.7+), чтобы иметь делегированную обработку событий, которая будет обрабатывать события для элементов, которые добавляются динамически.Примечание. .live() устарело во всех версиях jQuery, поэтому его больше не следует использовать.

Используя .on(), вы можете использовать это:

$("#attendance").on("keydown", "input:last", function(e) {
    if (e.which == 9) {
        var $this = $(this);
        var num = parseInt($this.attr('name').match(/\d+(,\d+)?/)[0]) + 1;
        $this.parent().append('<input type="text" name="attendance[' + num +']" value="Name and Position" class="medium" />');
    }
});

Использование .delegate() будетбыть похожим (кроме аргументов в другом порядке).Вы можете увидеть их оба в jQuery doc .delegate() и .on().

Делегированная обработка событий работает с использованием возможности "пузыривания" некоторых событий javascript,Это позволяет вам прикрепить обработчик событий к родительскому объекту (который не приходит и не уходит) и позволяет ему просматривать каждое событие, которое «всплывает» до него от дочернего объекта, проверять, происходит ли событие от объекта ссоответствующий селектор, и, если это так, выполните свой код обработки событий.Таким образом, когда объекты приходят и уходят, их события по-прежнему обрабатываются соответствующим образом.

Поскольку вы изначально делали что-то, вы привязывали бы обработчик событий непосредственно к объекту, который соответствовал селектору 'section#attendance input:last' в то время, когдакод привязки события выполнен.С тех пор он был привязан непосредственно к этому конкретному объекту независимо от того, соответствует ли этот объект селектору или добавляются ли новые объекты в DOM, которые будут соответствовать селектору.Делегированная обработка событий с использованием .delegate() или .on() позволяет поведению обработки событий быть более динамичным - автоматически приспосабливаясь к изменениям в DOM.Вам просто нужно привязать событие к общему родительскому объекту, который не будет изменяться, и он может автоматически отслеживать все его дочерние элементы.

5 голосов
/ 19 февраля 2012

Чтобы реагировать на динамически вставляемый контент, вам придется использовать делегированные события. В настоящее время рекомендуется использовать эту функцию: .on() (live устарело, bind и delegate заменены).

4 голосов
/ 19 февраля 2012

Не используйте вживую!Используйте on

Метод live устарел из-за плохой производительности, вместо этого используйте метод on .

$('section#attendance').on('keydown', 'input:last', function(e) {
    /* ... code ... */
});

Также нетпричина иметь тег section перед вашим селектором идентификатора.

1 голос
/ 19 февраля 2012

Скорее всего, проблема в том, что вы используете событие keydown. Это на самом деле использует связывание с селектором. Привязывайте только те эффекты, которые существуют, когда он впервые прикреплен. Документация JQuery гласит:

bind () прикрепляет события к элементам, которые существуют или соответствуют селектору во время вызова. Любые элементы, созданные после этого или совпадающие в будущем из-за изменения класса, не будут запускать связанное событие.

Вы должны заменить клавиатуру на что-то вроде следующего:

$('section#attendance).on("keydown", "input:last", function(e) {...});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...