What I'm trying to do
I just switched over from Font Awesome 4.7 to Font Awesome 5 and everything is working great except one thing: In part of my site, I use a font awesome icon as a toggle-esk button. On click, I want to change the "open" heart to a "closed" heart icon (fas fa-heart <-> far fa-heart). I can do this by changing the data-prefix in the SVG element in the browser's inspector.
Problem
My problem comes to binding the click listener as the element that was there is removed and replaced with an SVG. I dynamically add elements onto the page that have these heart icons and after generating the HTML with JS handlebars, I use jquerys .on("click") method to get when the button is clicked and toggle the classes. This was fine when the element didn't get replaced, but with the change to SVG's whats the new way of doing this?
Possible Solutions
I read through Font Awesome's "How To" guide and they don't cover topics like this yet. This is a common thing people will want to do so it would be nice to get a list of solutions people can use. Below are two ideas I've thought of but and one that FontAwesome would have to provide but I'm curious if there's a better way:
Example Fiddle
Here is a simplified example where a button is dynamically appended to the document (this works fine if using $(document).ready() but I am doing an API request and then generating html dynamically). Clicking the button does not call the listener as the element hasn't finished replacing the element to an 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");
});
This example works fine with FontAwesome 4.7 as the element isn't being replaced.
In best situation pointer-events: none;
will fix the svg
click listener issue. but in this case this solution not work. I have a better solution for you, set onclick
attribute on <i>
tag and handle a jquery
function with javascript
.
$("#heart").attr('onClick', 'callFunction(this)');
But as i said in comment
toggleClass
or anything for changing class
not solve your problem, because it convert <i>
tag to svg
so you can't change shape of heart by toggling class name. the only solution is change it before convert to svg
like this:
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;
}
}
Working Demo
Fontawsome has a great example of how to handle click events on their site.
This method worked great for me as I was looking to "toggleClass" onClick. Seems a bit simpler than the previous answer. I have tested this and it's working well.
document.addEventListener('DOMContentLoaded', function () {
$('button').on('click', function () {
$(this)
.find('[data-fa-i2svg]')
.toggleClass('fa-angle-down')
.toggleClass('fa-angle-right');
});
});
Examples Here
I decided to add my own example for anyone struggling with this:
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')
});
});
I'm using jQuery no-conflict and Bootstrap 4 accordion, WordPress. This is working great for me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With