El evento de clic de jquery no funciona después de agregar el método

82

Entonces, tengo este botón que agrega una nueva fila a la tabla, sin embargo, mi problema es que ya no escucha el .new_participant_formevento de clic después de que se haya realizado el método de adición.

http://jsfiddle.net/cTEFG/

Haga clic en Agregar nueva entrada y luego haga clic en el nombre del formulario.

$('#add_new_participant').click(function() {


    var first_name = $('#f_name_participant').val();
    var last_name = $('#l_name_participant').val();
    var role = $('#new_participant_role option:selected').text();
    var email = $('#email_participant').val();


    $('#registered_participants').append('<tr><td><a href="#" class="new_participant_form">Participant Registration</a></td><td>'+first_name+ ' '+last_name+'</td><td>'+role+'</td><td>0% done</td></tr>');

    });

    $('.new_participant_form').click(function() {

        var $td = $(this).closest('tr').children('td');

        var part_name = $td.eq(1).text();
        alert(part_name);

    });
});

HTML

<table id="registered_participants" class="tablesorter">

<thead>
<tr> 
<th>Form</th>
<th>Name</th>
<th>Role</th>
<th>Progress </th>


</tr> 
</thead>


<tbody>
<tr> 
<td><a href="#" class="new_participant_form">Participant Registration</a></td>
<td>Smith Johnson</td>
<td>Parent</td>
<td>60% done</td>


</tr> 
</tbody>

</table>

<button id="add_new_participant"></span>Add New Entry</button> 
Eduardo
fuente
El problema es que el evento solo se adjunta al new_participant_formelemento que ya está en el documento. Para que funcione para los elementos que también agregará más adelante, puede usar la delegación de eventos, como ha demostrado distrofia, o adjuntar el controlador a cada ancla antes de insertarla (la primera es más eficiente).
Asad Saeeduddin

Respuestas:

207

Usar en :

$('#registered_participants').on('click', '.new_participant_form', function() {

Para que el clic se delegue a cualquier elemento que #registered_participantstenga la clase new_participant_form, incluso si se agrega después de vincular el controlador de eventos.

Denys Séguret
fuente
4
¿Existe alguna desventaja con respecto al rendimiento, si lo usa $(document).on('click', '.new_participant_form', function() {});?
basZero
3
@basZero Hay uno, ya que jQuery tendría que manejar todos los clics y no solo el del, #registered_participantspero para ser justos, esta desaceleración es tan pequeña que es irrelevante. En general, es mejor apuntar al elemento correcto porque es más limpio.
Denys Séguret
34

El .on()método se utiliza para delegar eventos a elementos, agregados dinámicamente o ya presentes en el DOM:

// STATIC-PARENT              on  EVENT    DYNAMIC-CHILD
$('#registered_participants').on('click', '.new_participant_form', function() {

  var $td = $(this).closest('tr').find('td');
  var part_name = $td.eq(1).text();
  console.log( part_name );

});


$('#add_new_participant').click(function() {

  var first_name = $.trim( $('#f_name_participant').val() );
  var last_name  = $.trim( $('#l_name_participant').val() );
  var role       = $('#new_participant_role').val();
  var email      = $('#email_participant').val();
  
  if(!first_name && !last_name) return;

  $('#registered_participants').append('<tr><td><a href="#" class="new_participant_form">Participant Registration</a></td><td>' + first_name + ' ' + last_name + '</td><td>' + role + '</td><td>0% done</td></tr>');

});
<table id="registered_participants" class="tablesorter">
  <thead>
    <tr>
      <th>Form</th>
      <th>Name</th>
      <th>Role</th>
      <th>Progress </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#" class="new_participant_form">Participant Registration</a></td>
      <td>Smith Johnson</td>
      <td>Parent</td>
      <td>60% done</td>
    </tr>
  </tbody>
</table>

<input type="text" id="f_name_participant" placeholder="Name">
<input type="text" id="l_name_participant" placeholder="Surname">
<select id="new_participant_role">
  <option>Parent</option>
  <option>Child</option>
</select>
<button id="add_new_participant">Add New Entry</button>

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Leer más: http://api.jquery.com/on/

Roko C. Buljan
fuente
10

Este problema podría resolverse como se mencionó usando las .onversiones de jQuery 1.7+.

Desafortunadamente, esto no funcionó dentro de mi código (y tengo 1.11), así que usé:

$('body').delegate('.logout-link','click',function() {

http://api.jquery.com/delegate/

A partir de jQuery 3.0, .delegate () ha quedado obsoleto. Fue reemplazado por el método .on () desde jQuery 1.7, por lo que su uso ya estaba desaconsejado. Sin embargo, para versiones anteriores, sigue siendo el medio más eficaz para utilizar la delegación de eventos. Más información sobre el enlace y la delegación de eventos se encuentra en el método .on (). En general, estas son las plantillas equivalentes para los dos métodos:

// jQuery 1.4.3+
$( elements ).delegate( selector, events, data, handler );
// jQuery 1.7+
$( elements ).on( events, selector, data, handler );

¡Este comentario podría ayudar a otros :)!

W.Doch
fuente
1

PRUEBA ESTO

A partir de la versión 1.7+ de jQuery, el método on () es el nuevo reemplazo de los métodos bind (), live () y delegate ().

ASÍ QUE AGREGUE ESTO,

$(document).on("click", "a.new_participant_form" , function() {
      console.log('clicked');
});

O para más información CONSULTAR AQUÍ

Manoj
fuente
0

** Problema resuelto ** ingrese la descripción de la imagen aquí // Se cambió al método delegate () para usar la delegación del cuerpo

$("body").delegate("#boundOnPageLoaded", "click", function(){
   alert("Delegated Button Clicked")
});
Ashwani Garg
fuente
El método delegate () quedó obsoleto en la versión 3.0. Así que usa el método on () en su lugar.
Manoj