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 %}
{% with total_likes=post.users_like.count users_like=post.users_like.all %}
{{ total_likes }} like{{ total_likes|pluralize }}
{% if request.user not in users_like %}
{% else %}
{% endif %}
{% endwith %}
{% 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 eni
etiqueta objetivo actual serái
tag y no tienedata-action
atributo que es la razón por la que tu código no funciona. En su lugar puede comprobar sievent.target.tagName
esa
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); });
1274Respondida 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 eventoclick
, 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