2012-02-19 8 views
13

Mi selector es:selector de jQuery no se actualiza después de añadir nuevos elementos dinámicamente

$('section#attendance input:last') 

Sin embargo, añado otra entrada a la sección # asistencia. Quiero que el selector para seleccionar ahora ese elemento (como debe ser, debido a la :last Sin embargo, por alguna razón, no lo hace, y no estoy muy seguro de qué

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

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

EDIT: el problema parece estar en la "entrada: pasado, ya que funciona si sólo tiene que utilizar la entrada Además, si añado clase 'última' al. último elemento, funciona cuando uso 'input.last' como selector.

Respuesta

11

Dependiendo de qué versión de jQuery que está utilizando, se debe utilizar ya sea .delegate() (antes de jQuery 1.7) o .on() (jQuery 1.7+) tener delegado el manejo de eventos que manejará eventos para elementos que se agregan dinámicamente. La nota .live() ha quedado obsoleta en todas las versiones de jQuery, por lo que ya no se debe usar.

Usando .on(), puede utilizar esto:

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

Usando .delegate() sería similar (excepto los argumentos están en un orden diferente). Puede verlos en el documento de jQuery .delegate() y .on().

El manejo de eventos delegados funciona utilizando la capacidad de "burbujeo" de algunos eventos de JavaScript. Esto le permite adjuntar un controlador de eventos a un objeto principal (que no aparece y se va) y hacer que vea cada evento que "burbujee" desde un niño, verifique si el evento proviene de un objeto con un selector apropiado, y si es así, ejecute su código de manejo de eventos. De esta forma, a medida que los objetos van y vienen, sus eventos se manejan de manera apropiada.

Como originalmente estaba haciendo las cosas, vincularía el controlador de eventos directamente al objeto que coincidía con el selector 'section#attendance input:last' en el momento en que se ejecutó el código de vinculación de eventos.A partir de ese momento, se vinculó directamente a ese objeto específico independientemente de si ese objeto aún coincide con el selector o si se agregaron nuevos objetos al DOM que coincidirían con el selector. El manejo delegado de eventos usando .delegate() o .on() permite que el comportamiento de manejo de eventos sea más dinámico, ajustándose automáticamente a los cambios en el DOM. Solo tiene que vincular el evento a un objeto principal común que no cambiará y puede supervisar automáticamente todos sus elementos secundarios.

+1

Oye, probé esto, pero por alguna razón, parece que no funciona. Actualicé mi publicación con el nuevo código y revisé los documentos para .on(), pero no puedo determinar qué ocurre. ¡Saludos por la ayuda! – chintanparikh

+0

El problema es que la etiqueta de entrada que agrega no tiene el tipo correcto de atributo de nombre que su código espera. No divulgó su HTML, pero no me parece que su código pueda funcionar debido a la forma en que analiza el número del atributo de nombre. Su expresión regular coincide con dos números con una coma entre ellos, pero la nueva etiqueta de entrada que agrega no tiene ese formato. Puede ver una versión más simple trabajar aquí: http://jsfiddle.net/jfriend00/uVHwK/. Tendríamos que ver su HTML para asesorarlo más específicamente. – jfriend00

5

Para reaccionar al contenido insertado dinámicamente, deberá usar eventos delegados. La función actualmente recomendada para hacer esto es .on() (live está en desuso, bind y delegate están reemplazados).

+3

'bind' y' delegate' no están en desuso. –

+2

Tienes razón. 'live' está en desuso,' bind' y 'delegate' están reemplazados. – nijansen

1

Probablemente el problema se deba a que está utilizando el evento de selección de teclas. Eso realmente usa bind contra el selector. Enlace solo los elementos de efectos que existen cuando se adjunta por primera vez. Los documentos de JQuery dicen:

bind() ataca eventos a elementos que existen o coinciden con el selector en el momento en que se realiza la llamada. Cualquier elemento creado después o que coincida en el futuro porque la clase fue modificada, no activará el evento enlazado.

Usted debe mirar para reemplazar keydown con algo como lo siguiente:

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

¡No utilizar en vivo! Use on

El método en vivo ha quedado en desuso debido a un mal rendimiento, en su lugar, utilice el método on ahora.

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

También hay ninguna razón para tener la etiqueta section en frente de su selector de ID.

Cuestiones relacionadas