Подтвердить что ты не робот

Селектор jQuery не обновляется после динамического добавления новых элементов

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

$('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" в качестве селектора.

4b9b3361

Ответ 1

В зависимости от того, какую версию 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 .delegate() и .on().

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

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

Ответ 2

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

Ответ 3

Не используйте live! Используйте on

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

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

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

Ответ 4

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

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

Вы должны искать замену keydown следующим образом:

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