2012-02-19 7 views
13

mio selettore è:selettore jQuery non si aggiorna dopo l'aggiunta di nuovi elementi dinamicamente

$('section#attendance input:last') 

Tuttavia, aggiungo un altro ingresso alla sezione # presenze. Voglio il selettore per selezionare la società che elemento (come dovrebbe, a causa della :last Tuttavia, per qualche motivo, non è così, e io non sono troppo sicuro 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('<input type="text" name="attendance[' + num +']" value="Name and Position" class="medium" />'); 
     } 
    }); 

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('<input type="text" name="attendance[' + num +']" value="Name and Position" class="medium" />'); 
    } 
}); 

EDIT: il problema sembra essere sulla 'ingresso: ultima', come funziona, se mi basta usare ingresso Inoltre, se aggiungo classe 'ultima' al. ultimo elemento, funziona quando uso 'input.last' come selettore

risposta

11

A seconda di quale versione di jQuery che si sta utilizzando, si dovrebbe utilizzare .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 aggiunti dinamicamente. Nota .live() è stato deprecato da tutte le versioni di jQuery, quindi non dovrebbe più essere utilizzato.

Utilizzando .on(), è possibile utilizzare 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('<input type="text" name="attendance[' + num +']" value="Name and Position" class="medium" />'); 
    } 
}); 

Utilizzando .delegate() sarebbe simile (tranne gli argomenti sono in un ordine diverso). Puoi visualizzarli entrambi nel documento jQuery .delegate() e .on().

Gestione eventi delegata funziona con la funzionalità "bubbling" di alcuni eventi javascript. Questo ti permette di collegare un gestore di eventi a un oggetto 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 oggetto 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.

Come inizialmente si stavano facendo le cose, si sarebbe associato il gestore di eventi direttamente all'oggetto che corrispondeva al selettore 'section#attendance input:last' al momento in cui il codice di associazione degli eventi è stato eseguito.Da quel momento in poi, è stato associato direttamente a quell'oggetto specifico indipendentemente dal fatto che quell'oggetto corrisponda ancora al selettore o se nuovi oggetti vengano aggiunti al DOM che corrispondano al selettore. La gestione degli eventi delegati utilizzando .delegate() o .on() consente al comportamento di gestione degli eventi di essere più dinamico, adattandosi automaticamente alle modifiche nel DOM. Devi solo legare l'evento a un oggetto genitore comune che non cambierà e può monitorare automaticamente tutti i suoi figli.

+1

Ehi, ci ho provato, ma per qualche motivo, non sembra funzionare. Ho aggiornato il mio post con il nuovo codice e ho esaminato i documenti per .on(), ma non riesco a capire cosa c'è che non va. Saluti per l'aiuto! – chintanparikh

+0

Il problema è che il tag di input che aggiungi non ha il giusto tipo di attributo del nome che il tuo codice si aspetta. Non hai rivelato il tuo codice HTML, ma non mi sembra che il tuo codice possa funzionare a causa del modo in cui analizza il numero dall'attributo name. Il tuo regex corrisponde a due numeri con una virgola in mezzo, ma il nuovo tag di input che aggiungi non ha quel formato. Puoi vedere una versione più semplice da lavorare qui: http://jsfiddle.net/jfriend00/uVHwK/. Dovremmo vedere il tuo codice HTML per avvisare in modo più specifico. – jfriend00

5

Per rispondere ai contenuti inseriti dinamicamente, sarà necessario utilizzare gli eventi delegati. La funzione attualmente raccomandata per fare ciò è .on() (live è obsoleto, bind e delegate sono superati).

+3

'bind' e' delegate' non sono deprecati. –

+2

Hai ragione. 'live' è deprecato,' bind' e 'delegate' sono superati. – nijansen

1

Il problema più probabile è perché si sta utilizzando l'evento keydown. In realtà utilizza il legame con il selettore. Vincola solo gli effetti che esistono quando viene allegato per la prima volta. La documentazione JQuery dice:

bind() associa eventi a 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 classe è stata modificata, non generano l'evento associato.

Si dovrebbe cercare di sostituire keydown con qualcosa come il seguente:

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

Non utilizzare live! Utilizzare on

Il metodo live è stato deprecato a causa di prestazioni non corrette, utilizzare ora il metodo on.

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

Inoltre c'è alcun motivo per avere il tag section davanti al selettore di ID.

Problemi correlati