O seletor do jQuery não é atualizado depois de adicionar dinamicamente novos elementos

Meu seletor é:

$('section#attendance input:last') 

No entanto, incluo outra input na seção # attendance. Eu quero que o seletor agora selecione esse elemento (como deveria, por causa do :last . No entanto, por algum motivo, isso não acontece, e eu não estou muito certo do porquê?

Aqui está o meu código completo:

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

Novo Código:

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

EDIT: O problema parece estar no ‘input: last’, como funciona se eu apenas usar input. Além disso, se eu adicionar a class ‘last’ ao último elemento, isso funcionará quando eu usar ‘input.last’ como um seletor.

Dependendo de qual versão do jQuery você está usando, você deve usar .delegate() (antes do jQuery 1.7) ou .on() (jQuery 1.7+) para ter manipulação de events delegada que manipulará events para elementos adicionados dinamicamente. Nota. .live() foi preterido em todas as versões do jQuery, portanto, ele não deve mais ser usado.

Usando .on() , você pode usar isto:

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

Usando .delegate() seria semelhante (exceto os argumentos estão em uma ordem diferente). Você pode ver ambos no jQuery doc .delegate() e .on() .

A manipulação de events delegada funciona usando o recurso “bubbling” de alguns events de javascript. Isso permite que você anexe um manipulador de events a um object pai (que não vem e vá) e faça com que ele veja cada evento que “borbulha” de um filho, verifique se o evento vem de um object com um seletor apropriado e, se for o caso, execute seu código de manipulação de events. Dessa forma, à medida que os objects vêm e vão, seus events ainda são tratados de maneira apropriada.

Como você estava originalmente fazendo as coisas, você ligaria o manipulador de events diretamente ao object que correspondia ao seletor 'section#attendance input:last' no momento em que o código de binding do evento foi executado. A partir de então, ele foi ligado diretamente a esse object específico, independentemente de o object ainda corresponder ao seletor ou de novos objects serem adicionados ao DOM que correspondam ao seletor. O tratamento de events delegates usando .delegate() ou .on() permite que o comportamento de manipulação de events seja mais dynamic – ajustando-se automaticamente às alterações no DOM. Você só precisa vincular o evento a um object pai comum que não será alterado e pode monitorar automaticamente todos os seus filhos.

Para reagir ao conteúdo inserido dinamicamente, você precisará usar events delegates. A function atualmente recomendada para fazer isso é .on() ( live é reprovado, bind e delegate são substituídos).

Não use ao vivo! Usar em

O método ao vivo foi preterido devido ao mau desempenho, use o método on agora.

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

Também não há razão para ter a tag de section na frente do seu seletor de ID.

O problema provavelmente é porque você está usando o evento keydown. Isso realmente usa bind contra o seletor. Vincule apenas itens de efeitos que existem quando são anexados pela primeira vez. A documentação do JQuery diz:

bind () anexa events a elementos que existem ou correspondem ao seletor no momento em que a chamada é feita. Quaisquer elementos criados posteriormente ou que correspondam daqui para frente porque a class foi alterada, não triggersrão o evento vinculado.

Você deve procurar replace o keydown com algo como o seguinte:

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