En mi sitio web tengo una tabla con algunos enlaces "agregar". Al hacer clic en los enlaces de agregar, se activa una solicitud ajax y, tan pronto como se haya realizado esta solicitud, se crea una nueva fila de la tabla directamente debajo de la fila del enlace "agregar".
Al hacer clic en un solo enlace "agregar" a la vez, la secuencia de comandos funciona como se esperaba.
Sin embargo, el script llamado por la solicitud de obtención tiene un tiempo de ejecución de aproximadamente 2 segundos. Entonces podría suceder que las solicitudes se ejecuten en paralelo.
En caso de que haga clic en el segundo enlace "agregar" mientras el primero aún se está cargando, las dos filas nuevas se agregan debajo de la segunda fila de la tabla. Por otro lado, al hacer clic en el primer enlace "agregar" mientras el segundo aún se está cargando, ambas filas nuevas se agregan debajo de la primera fila de la tabla. (así que entre los dos agregar enlaces).
Este no es el comportamiento que quería tener: espero que al hacer clic en ambos enlaces "agregar" obtenga una nueva fila después de cada una de las filas.
Supongo que esto podría suceder, porque la variable "clic" se sobrescribe al cargar la segunda respuesta mientras la primera respuesta aún se está ejecutando. ¿Cómo puedo prevenir este comportamiento?
$('a.open').bind('click', function () { id=$(this).attr('id'); click=$(this); $.get("#", {key:id}) .done(function( data ) { text=data.html; click.closest('tr').after('<tr><td></td><td>'+text+'</td></tr>'); }) .fail(function (jqXHR, textStatus) { click.closest('tr').after('<tr><td></td><td>error</td></tr>'); }); }); <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <table border=1> <tr> <td><a href="#" id="12333" class="open">add</a></td> <td>some text</td> </tr> <tr> <td><a href="#" id="23457" class="open">add</a></td> <td>some other text</td> </tr> </table>De hecho, el problema es que los valores de id y click se sobrescriben antes de que finalice la llamada AJAX.
Esto sucede porque no usa una palabra clave variable, como var , let o const para declarar su variable. Por lo tanto, la id y el click se asignarán como propiedades al objeto de la window . Puede probarlo iniciando sesión window.id dentro de la función.
$('a.open').on('click', function() { id = $(this).attr('id'); console.log(window.id); }); <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <table border=1> <tr> <td><a href="#" id="12333" class="open">add</a></td> <td>some text</td> </tr> <tr> <td><a href="#" id="23457" class="open">add</a></td> <td>some other text</td> </tr> </table> Puedes resolver esto usando const o let . Ambas son variables locales con alcance de bloque, lo que significa que solo existen dentro del alcance en el que se encuentran. En este caso, solo existen dentro de la function() { ... } que maneja su evento de clic.
var también lo hará, pero recomendaría mirar los dos primeros, ya que permiten un mayor control con el alcance.
$('a.open').on('click', function() { const id = $(this).attr('id'); const click = $(this); setTimeout(function() { click.closest('tr').after('<tr><td></td><td>Foobar</td></tr>'); }, 3000); }); <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <table border=1> <tr> <td><a href="#" id="12333" class="open">add</a></td> <td>some text</td> </tr> <tr> <td><a href="#" id="23457" class="open">add</a></td> <td>some other text</td> </tr> </table>