Ce que j'essaie de faire
Je viens de passer de Font Awesome 4.7 à Font Awesome 5 et tout fonctionne très bien, sauf une chose: sur une partie de mon site, j'utilise une icône de police géniale comme bouton de basculement. Au clic, je veux changer le coeur "ouvert" en une icône de coeur "fermé" (fas fa-heart <-> far fa-heart). Je peux le faire en modifiant le préfixe de données dans l'élément SVG de l'inspecteur du navigateur.
Problème
Mon problème vient de lier l'auditeur de clic car l'élément qui était là est supprimé et remplacé par un SVG. J'ajoute dynamiquement des éléments à la page qui ont ces icônes de cœur et après avoir généré le code HTML avec le guidon JS, j'utilise la méthode jquerys .on ("clic") pour obtenir un clic sur le bouton et basculer les classes. C'était bien quand l'élément n'a pas été remplacé, mais avec le changement de SVG, quelle est la nouvelle façon de procéder?
Solutions possibles
J'ai lu le guide "Comment faire" de Font Awesome et ils ne traitent pas encore de sujets comme celui-ci. C’est une chose commune que les gens voudront faire, alors il serait agréable d’obtenir une liste des solutions que les gens peuvent utiliser. Vous trouverez ci-dessous deux idées auxquelles j'ai pensé mais une idée que FontAwesome devrait fournir, mais je suis curieux de savoir s'il existe un meilleur moyen:
Exemple Fiddle
Voici un exemple simplifié dans lequel un bouton est ajouté dynamiquement au document (cela fonctionne correctement si vous utilisez $ (document) .ready (), mais je fais une demande d'API puis je génère html de manière dynamique). Le fait de cliquer sur le bouton n'appelle pas l'auditeur car l'élément n'a pas fini de remplacer l'élément par un fichier SVG.
https://jsfiddle.net/L748ownw/
<div id='container'></div>
$("#container").append("<i id='heart' class='far fa-heart'></i>");
$(".far").on("click", function() {
console.log("clicked");
});
Cet exemple fonctionne bien avec FontAwesome 4.7 car l’élément n’est pas remplacé.
Dans le meilleur des cas, pointer-events: none;
résoudra le problème de _svg
click listener. mais dans ce cas, cette solution ne fonctionne pas. J'ai une meilleure solution pour vous, définissez l'attribut onclick
sur la balise <i>
et gérez une fonction jquery
avec javascript
.
$("#heart").attr('onClick', 'callFunction(this)');
Mais comme je l’ai dit dans comment
toggleClass
ou quoi que ce soit pour changer class
ne résoudra pas votre problème, car il convertit la balise <i>
en svg
de sorte que vous ne pouvez pas changer de forme de cœur en changeant le nom de classe. la seule solution est de le changer avant de le convertir en svg
comme ceci:
var click = false;
function callFunction(el) {
if (!click) {
$("#container").empty().append("<i id='heart' class='fas fa-heart'></i>");
$("#heart").attr('onClick', 'callFunction(this)');
click = true;
} else {
$("#container").empty().append("<i id='heart' class='far fa-heart'></i>");
$("#heart").attr('onClick', 'callFunction(this)');
click = false;
}
}
Fontawsome a un excellent exemple de la façon de gérer les événements liés aux clics sur leur site.
Cette méthode a très bien fonctionné pour moi alors que je cherchais à "toggleClass" onClick. Cela semble un peu plus simple que la réponse précédente. J'ai testé cela et ça marche bien.
document.addEventListener('DOMContentLoaded', function () {
$('button').on('click', function () {
$(this)
.find('[data-fa-i2svg]')
.toggleClass('fa-angle-down')
.toggleClass('fa-angle-right');
});
});
J'ai décidé d'ajouter mon propre exemple à toute personne aux prises avec ce problème:
document.addEventListener('DOMContentLoaded', function () {
jQuery('.ppolicy-link').on('click', function () {
var collapsed=jQuery(this).find('[data-fa-i2svg]').hasClass('fa-plus-square');
jQuery('.btn-link').find('[data-fa-i2svg]').removeClass('fa-minus-square');
jQuery('.btn-link').find('[data-fa-i2svg]').addClass('fa-plus-square');
if(collapsed)
jQuery(this).find('[data-fa-i2svg]').toggleClass('fa-plus-square fa-minus-square')
});
});
J'utilise jQuery no-conflict et Bootstrap 4 accordéon, WordPress. Cela fonctionne très bien pour moi.