Las funciones AJAX/jquery solo funcionan una vez por carga de página

Estoy creando una lista dinámica de tareas pendientes. La lista se descarga de una base de datos local y se muestra en una tabla. En cada tarea hay un botón de envío que puede presionar y se supone que la tarea debe registrarse en la base de datos como "hecha". En mi código esto se hace a través de una variable llamada estado en la que se hace un valor de 1 y se deshace un valor de 0.

Mi problema es que puedes presionar cualquier botón y todo funciona bien; El nuevo estado se envía a un script PHP, que a su vez modifica el valor del estado en la base de datos. Luego, la página web actualiza automáticamente la tabla de visualización. Pero si lo intentas una vez más, en cualquiera de los otros botones, no funciona. Tendrá que volver a cargar la página web para que funcione cualquiera de los otros botones.

Aquí está mi código Jquery/AJAX:

        $(document).ready( function() {
            $('#todo_display_table input[type="submit"]').click(function(evt) {
               evt.preventDefault();

               var todo_id = $(this).val();
               //document.write(todo_id);//debug
               $.when(changeTodoStatusTo(1, todo_id)).then(updateTodoDisplay);
            });
        });

        function updateTodoDisplay() {
            $.post("./daily_todo_display.php", null, replaceTbodyHTML);
        }

        function replaceTbodyHTML(data) {
            $('#todo_display_table tbody').html(data);
        }

        function changeTodoStatusTo(newStatus, todo_id) {
            //Send til phpscript som lagrer ny status i databasen
            var parameters = {
                todo_id: todo_id,
                newStatus: newStatus
            };

            return $.post("./daily_todo_change_todo_status.php", parameters); //, printDebugInfo);
        }

También puedo publicar mis scripts PHP, pero los he probado por separado y parecen funcionar. Una vez más, todas las funciones de mi página funcionan bien, pero parecen dejar de funcionar después de hacer clic una vez.

Revisé la base de datos y el valor de estado solo se actualizó en el primer intento (primer clic en cualquiera de los botones), lo que indicaría que el problema radica en la función click() o en la función changeTodoStatusTo(). Gracias por cualquier ayuda, y no dude en pedir más información =)

preguntado el 21 de mayo de 12 a las 19:05

¡Gracias por varias buenas respuestas! -

6 Respuestas

No debe usar la función en vivo de jQuery:

A partir de jQuery 1.7, el método .live () está obsoleto. Utilice .on () para adjuntar controladores de eventos. Los usuarios de versiones anteriores de jQuery deben usar .delegate () en lugar de .live ().

Este método proporciona un medio para adjuntar controladores de eventos delegados al elemento de documento de una página, lo que simplifica el uso de controladores de eventos cuando el contenido se agrega dinámicamente a una página. Consulte la discusión de eventos directos versus delegados en el método .on() para obtener más información.

documentación en vivo de jQuery

Como dice la documentación, use .on() en su lugar. Funciona de la misma manera que .live() :)

Respondido el 20 de junio de 20 a las 10:06

¿Estás recreando los botones de envío cuando actualizas? Es difícil saberlo sin ver todo el código. Has probado a cambiar esto:

$('#todo_display_table input[type="submit"]').click(function(evt) {

a esto:

$('#todo_display_table input[type="submit"]').live('click', function(evt) {

mira esto si aplica: http://api.jquery.com/live/

contestado el 21 de mayo de 12 a las 19:05

Solo para explicar un poco más el cambio, cuando vincula un evento de clic como este $(...).click() entonces se aplica a todos los elementos actualmente en la página. Los elementos nuevos que coincidan con ese selector que se agreguen a la página no tendrán el evento de clic vinculado. Si hace esto $(...).live('click'), entonces el oyente se vinculará automáticamente a cualquier elemento nuevo que coincida con ese selector. En este caso, si está recreando los botones de envío a través de ajax, entonces necesita usar "en vivo". - Por gracia

¡Funcionó! Respuesta realmente útil con una buena explicación, gracias;) - Einar

@Einar Eche un vistazo a la documentación de la función en vivo. No deberías usarlo más. - Andreas Estocolmo

Es cierto, debería comenzar a usar "on". Live siempre ha funcionado, así que no me he molestado en cambiar. Encontré que esta es una buena explicación. Es un poco más claro/conciso que la documentación de jquery: stackoverflow.com/questions/8065305/… - Por gracia

Usando on() ahora ;) Pero un poco decepcionado de que el selector no vaya $(aquí) con la función on(). Pero gracias a los dos, ahora funciona sin problemas =) - Einar

Supongo que estás perdiendo el click código de evento cuando actualice el html() de los #todo_display_table. Intentar live()

$('#todo_display_table input[type="submit"]').live('click', function(evt) {

contestado el 21 de mayo de 12 a las 19:05

Este es un caso clásico de almacenamiento en caché del navegador. Experimenté el mismo efecto hace un tiempo. Una salida sería invocar todas tus publicaciones como tales:

$.post("./daily_todo_change_todo_status.php?id=" + (count++), parameters);

Dentro de su script php, simplemente ignore el componente id. Al hacerlo de esta manera, el navegador generará una nueva cadena cada vez y no pensará que estaba llamando a la página anterior almacenada en caché.

Espero que haya ayudado :) ¡Salud!

contestado el 21 de mayo de 12 a las 19:05

Parece que está enfrentando algunos problemas con el navegador que almacena en caché la respuesta de sus solicitudes POST. Este es un problema común con algunos navegadores. Debe saber que los navegadores almacenan en caché el contenido en función del URI, no del archivo real. En otras palabras, se incluye la cadena de consulta. Una solución para evitar el almacenamiento en caché de las solicitudes es usar un URI ligeramente diferente cada vez:

$.post("./daily_todo_change_todo_status.php?t="+new Date().getTime(), null, callbackFn);

Al insertar la marca de tiempo actual, tiene la garantía de realizar siempre una nueva solicitud al servidor, en lugar de que el navegador simplemente extraiga los datos almacenados en caché en lugar de una solicitud.

Además, en su segunda solicitud POST, está intentando devolver datos. Esta función está diseñada para devolver la respuesta y procesarla dentro de una función de devolución de llamada, de forma asíncrona, para que no bloquee la ejecución en la página.

Sin embargo, veo que tiene un comentario allí que es para depurar información, así que espero que esto sea algo que eliminaría en producción.

contestado el 21 de mayo de 12 a las 19:05

Por el código que puedo ver, su manejo de eventos parece estar bien. Sin embargo, lo más probable es que pierda los eventos cuando replaceTbodyHTML se llama. Puede intentar ejecutar el código desde la carga nuevamente cuando actualice. Por ejemplo,

function addListeners() {
    $('#todo_display_table input[type="submit"]').click(function(evt) {
        evt.preventDefault();

        var todo_id = $(this).val();
        //document.write(todo_id);//debug
        $.when(changeTodoStatusTo(1, todo_id)).then(updateTodoDisplay);
    });
}

$(document).ready(addListeners);

Y luego al final de replaceTbodyHTML add addListeners();

contestado el 21 de mayo de 12 a las 19:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.