Il selettore jQuery non si aggiorna dopo l’aggiunta dynamic di nuovi elementi

Il mio selezionatore è:

$('section#attendance input:last') 

Tuttavia, aggiungo un altro input alla sezione # attendance. Voglio che il selettore ora selezioni quell’elemento (come dovrebbe, a causa di :last last.Tuttavia, per qualche ragione, non lo è, e non sono troppo sicuro del perché?

Ecco il mio codice 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(''); } }); 

Nuovo codice:

  $("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: Il problema sembra essere “input: last”, come funziona se uso solo input. Inoltre, se aggiungo la class ‘last’ all’ultimo elemento, funziona quando uso ‘input.last’ come selettore.

A seconda della versione di jQuery che stai usando, dovresti usare .delegate() (prima di jQuery 1.7) o .on() (jQuery 1.7+) per avere una gestione degli eventi delegata che gestirà gli eventi per gli elementi che vengono aggiunti dynamicmente. Nota .live() è stato deprecato da tutte le versioni di jQuery, quindi non dovrebbe più essere utilizzato.

Usando .on() , puoi usare questo:

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

L’uso di .delegate() sarebbe simile (eccetto che gli argomenti sono in un ordine diverso). Puoi vederli entrambi in jQuery doc .delegate() e .on() .

La gestione degli eventi delegati funziona con la funzionalità “bubbling” di alcuni eventi javascript. Questo ti permette di colbind un gestore di eventi a un object genitore (che non va e viene) e fare in modo che guardi ogni evento che “bolle” da un bambino, controlla se l’evento proviene da un object con un selettore appropriato, e in tal caso, eseguire il codice di gestione degli eventi. In questo modo, mentre gli oggetti vanno e vengono, i loro eventi vengono comunque gestiti in modo appropriato.

Dato che inizialmente facevi cose, dovresti associare direttamente il gestore di eventi all’object che corrispondeva al numero di selezione 'section#attendance input:last' del selettore 'section#attendance input:last' al momento dell’esecuzione del codice di bind dell’evento. Da quel momento in poi, è stato associato direttamente a quell’object specifico indipendentemente dal fatto che quell’object corrisponda ancora al selettore o se nuovi oggetti vengano aggiunti al DOM che corrispondano al selettore. La gestione degli eventi delegati mediante .delegate() o .on() consente al comportamento di gestione degli eventi di essere più dinamico, adattandosi automaticamente alle modifiche nel DOM. Devi solo bind l’evento a un object genitore comune che non cambierà e può monitorare automaticamente tutti i suoi figli.

Per reactjs ai contenuti inseriti dynamicmente, dovrai utilizzare gli eventi delegati. La funzione attualmente raccomandata per fare ciò è .on() ( live è deprecato, bind e delegate sono sostituiti).

Non usare live! Usa su

Il metodo live è stato deprecato a causa di prestazioni inadeguate, ora invece usa il metodo on .

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

Inoltre non c’è motivo di avere il tag di section davanti al tuo selettore di ID.

Il problema più probabile è perché stai usando l’evento keydown. In realtà utilizza il legame con il selettore. Vincola solo gli effetti che esistono quando viene allegato per la prima volta. I documenti JQuery dice:

bind () allega gli eventi agli elementi esistenti o corrispondenti al selettore nel momento in cui viene effettuata la chiamata. Tutti gli elementi creati successivamente o che corrispondono alla funzione successiva perché la class è stata modificata, non generano l’evento associato.

Dovresti cercare di sostituire il keydown con qualcosa del tipo:

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