Fuente impresionante No cambiar asincrónicamente con un cambio de clase usando Ajax

Tengo un botón de amor (hecho con fuente impresionante Icon) que debe cambiar cada vez que un usuario hace clic en él, pero cuando hago clic en él, sólo cambia por ejemplo de sólido completo a vacío cuando recarga la página.

Para cambiar el icono, el enfoque que uso está cambiando la clase de fuente impresionante en cada clic

parte exacta responsable del comportamiento del botón

if (previous_action == 'like')
{
    $(event.target).find("i").removeClass("far fa-heart").addClass("fas fa-heart")
}
            
else {
    $(event.target).find("i").removeClass("fas fa-heart").addClass("far fa-heart")
     }

código completo

$('a.like').on('click', function(event){
    event.preventDefault();
    event.stopPropagation();
    event.stopImmediatePropagation();

    $.post('{% url "posts:post_like" %}',
      {
        id: $(this).data('id'),
        action: $(this).data('action')
      },
      function(data){
        if (data['status'] == 'ok')
        {
            var previous_action = $(event.target).data('action');
            

            // toggle data-action
            $(event.target).data('action', previous_action == 'like' ?
            'unlike' : 'like');

            
            // toggle class to change icon
            if (previous_action == 'like')
            {
                $(event.target).find("i").removeClass("far fa-heart").addClass("fas fa-heart")
            }
            
            else {
                $(event.target).find("i").removeClass("fas fa-heart").addClass("far fa-heart")
            }
            
            
            // update total likes
            var previous_likes = parseInt($(event.target).closest("div").find("span.count .total").text());
            $(event.target).closest("div").find("span.count .total").text(previous_action == 'like' ? previous_likes + 1 : previous_likes - 1);
        }
      }
    );
  });

Extracto HTML

{% for post in posts %}
       
            
        
{% endfor %}

Extracto de enlaces


    

Pregunta hecha hace 3 años, 4 meses, 26 días - Por codealchemy


3 Respuestas:

  • En su código actual usted tiene uso $(event.target) así que cuando haga clic en i etiqueta objetivo actual será i tag y no tiene data-action atributo que es la razón por la que tu código no funciona. En su lugar puede comprobar si event.target.tagName es a etiquetar o no utilizar esto puede modificar nuestro selector .

    Código de Demo :

    $('a.like').on('click', function(event) {
      event.preventDefault();
      event.stopPropagation();
      event.stopImmediatePropagation();
      //your ajax calll..
      //other codes ..
      //check if the event target elemnt is `a` tag or not 
      var target = event.target.tagName.toLowerCase() === 'a' ? $(event.target) : $(event.target).closest("a")
      //use target then..
      var previous_action = target.data('action');
      console.log(previous_action)
      target.data('action', previous_action == 'like' ?
        'unlike' : 'like');
      if (previous_action == 'like') {
        target.find("i").removeClass("fas fa-heart").addClass("far fa-heart")
      } else {
        target.find("i").removeClass("far fa-heart").addClass("fas fa-heart")
      }
      var previous_likes = parseInt($(event.target).closest("div").find("span.count .total").text());
      $(event.target).closest("div").find("span.count .total").text(previous_action == 'like' ? previous_likes + 1 : previous_likes - 1);
    
    });
    
    
    
    
      
    
    
      
    

    Respondida el Dec 20, 2020 a las 15:37 - por techtactician

    Votos positivos: 0 | Votos negativos: 0

  • El problema que estás experimentando con la fuente impresionante que no cambia asincrónicamente con un cambio de clase usando Ajax puede deberse a que estás tratando de acceder al elemento incorrecto en tu evento click. En la parte exacta responsable del comportamiento del botón, estás usando $(event.target).find("i") para encontrar el icono en el evento click, pero esto puede no estar apuntando al elemento correcto en cada clic.

    Para asegurarte de que estás cambiando la clase del icono correcto, te sugiero que uses $(this) en lugar de $(event.target) para acceder al elemento que está siendo clicado. De esta manera, el código debería verse así:

    js
    if (previous_action == 'like') {
        $(this).find("i").removeClass("far fa-heart").addClass("fas fa-heart");
    } else {
        $(this).find("i").removeClass("fas fa-heart").addClass("far fa-heart");
    }
    

    Al usar $(this) en lugar de $(event.target), puedes asegurarte de que estás accediendo al icono correcto que está siendo clicado y cambiar su clase correctamente.

    Prueba esta modificación en tu código y verifica si ahora el cambio de clase del icono se realiza de forma asincrónica cuando un usuario hace clic en él.

    Respondida el Dec 21, 2020 a las 15:39 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • El problema es que el servidor no está respondiendo lo suficientemente rápido para que el código JavaScript pueda cambiar la clase de fuente impresionante antes de que se vuelva a cargar la página.

    Para resolver este problema, puedes intentar lo siguiente:

    • Asegúrate de que el servidor esté respondiendo rápidamente. Puedes utilizar una herramienta como WebPageTest para comprobar el rendimiento de tu servidor.
    • Utiliza una solicitud AJAX para enviar los datos al servidor. Esto evitará que la página se vuelva a cargar. Puedes utilizar la función `$.ajax()` de jQuery para hacer esto.
    • Utiliza la propiedad `async: false` en la solicitud AJAX. Esto asegurará que el código JavaScript espere a que el servidor responda antes de continuar.

    Aquí tienes un ejemplo de cómo puedes utilizar una solicitud AJAX para enviar los datos al servidor:

    javascript
    $('a.like').on('click', function(event){
        event.preventDefault();
        event.stopPropagation();
        event.stopImmediatePropagation();
    
        $.ajax({
            url: '{% url "posts:post_like" %}',
            type: 'POST',
            data: {
                id: $(this).data('id'),
                action: $(this).data('action')
            },
            async: false,
            success: function(data){
                if (data['status'] == 'ok')
                {
                    var previous_action = $(event.target).data('action');
    
                    // toggle data-action
                    $(event.target).data('action', previous_action == 'like' ?
                    'unlike' : 'like');
    
                    // toggle class to change icon
                    if (previous_action == 'like')
                    {
                        $(event.target).find("i").removeClass("far fa-heart").addClass("fas fa-heart")
                    }
    
                    else {
                        $(event.target).find("i").removeClass("fas fa-heart").addClass("far fa-heart")
                    }
    
    
                    // update total likes
                    var previous_likes = parseInt($(event.target).closest("div").find("span.count .total").text());
                    $(event.target).closest("div").find("span.count .total").text(previous_action == 'like' ? previous_likes + 1 : previous_likes - 1);
                }
            }
        });
    });
    

    Espero que esto resuelva tu problema. Avísame si tienes alguna otra pregunta.

    Respondida el Dec 21, 2020 a las 15:46 - por Gemini

    Votos positivos: 0 | Votos negativos: 0