1

Assume I have the following css:

<style>
  .liked { 
      color: #600;
   }

   .not-liked {
       color: #aaa;
   }
</style>

Assuming I have this: <i class = 'fa fa-heart-o not-liked' id = "banner"></i>

in my jQuery, if I swap classes from not-liked to liked can I also swap fa-heart-o to fa-heart in the same class?

So I'm trying to avoid this:

function() {
   $("#banner").removeClass('not-liked');
   $("#banner").removeClass('fa-heart-o');
   $("#banner").addClass('liked');
   $("#banner").addClass('fa-heart');
}

and basically switch the colour and the icon with this:

function() {
   $("#banner").removeClass('not-liked');
   $("#banner").addClass('liked');
}
StackOverflowed
  • 5,854
  • 9
  • 55
  • 119
  • 1
    You should use only a single class to track liked or not-liked. By default give `fa` the color for not-liked. Keep only a class called say `liked`. Then use `toggleClass` to change the color. If you are changing the font you have to do it the way you are doing/ by chaining. – user3613129 Mar 14 '16 at 04:50
  • You can swap out the icon by using the `content` CSS property though :). Will follow up with an example. – user3613129 Mar 14 '16 at 04:53
  • btw you can just chain jQuery... `$("#banner").removeClass('not-liked').addClass('liked');`. – Erik Philips Mar 14 '16 at 05:16

4 Answers4

4

FontAwesome glyphicons can be accessed via their Unicode identifiers. In fact, all the predefined classes provided by the stylesheet are created in the same way, using the ::before pseudo-element selector, and content.

We can see fa-heart is f004, and fa-heart-o is f08a.

If you want to reduce the class list overhead, for both your HTML and JavaScript, just adjust your own classes to represent exactly what you need.

$('.toggle').on('click', function () {
  $(this).toggleClass('not-liked liked');
});

$('.once').on('click', function () {
  $(this).removeClass('not-liked').addClass('liked');
});
.liked::before {
  color: #600;
  content: '\f004';
}

.not-liked::before {
  color: #aaa;
  content: '\f08a';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">

<span class='toggle fa not-liked'></span>
<span class='once fa not-liked'></span>
Oka
  • 23,367
  • 6
  • 42
  • 53
  • I'm not downvoting, however you've hard coded values so if Font-Awesome decides to change the value of `\f004` or `\f08a` your code breaks, but anyone using the class names won't. This is tightly coupled code, I don't recommend it. – Erik Philips Mar 16 '16 at 16:14
  • @ErikPhilips Here's the [FA v1.0 release from March 9, 2012](https://github.com/FortAwesome/Font-Awesome/blob/b72f07fc7c1d194517a5f7ae38fafc498927d5a9/css/font-awesome.css). You might be interested to learn that after four years, and four major releases, the Unicode identifiers for the heart, and it's empty counterpart, have never changed - but their class identifiers _have_. One way or another, you have to hard code _something_, or _nothing_ would ever get written. This is why we use versioned code. – Oka Mar 16 '16 at 18:28
  • I prefer [programming to an interface](http://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface) (class) than a concrete type (had coded value). That is to code to what they expose through documentation. – Erik Philips Mar 16 '16 at 19:00
2

try with this below code and you can continue to remove and add classes using jquery

$( "i#banner" ).click(function() {
  $(this).toggleClass( "fa-heart-o not-liked fa-heart liked" );
});
.liked { 
  color: #600;
}

.not-liked {
  color: #aaa;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>

<i class = 'fa fa-heart-o not-liked' id="banner"></i>
<i class = 'fa fa-heart-o not-liked' id="banner"></i>
<i class = 'fa fa-heart-o not-liked' id="banner"></i>
Iqbal Pasha
  • 1,318
  • 1
  • 8
  • 12
1
<i class = 'fa fa-heart-o not-liked' id = "#banner"></i>

In the code you mentioned above, make sure that,

id = "banner" instead of id = "#banner"

Then you can continue to remove and add classes using jquery; your solution would work just fine or I do prefer the solution provided by @Russel

absingharora
  • 134
  • 11
1

I highly recommend reading Decoupling Your HTML, CSS, and JavaScript - Philip Walton @ Google.

IMO, your code is to tightly coupled. Instead of tying everything together, take advantage of css as much as possible:

$(document).ready(function(){
  $(".js-update-heart").on("click", function(){
    $(this).toggleClass('is-liked is-not-liked');
    });
  });
.banner .fa{
  display: none;
  cursor: pointer;
}

.banner .fa-heart-o { 
  color: #600;
}

.banner .fa-heart {
  color: #aaa;
}

.banner.is-liked .fa-heart{
  display: inline;
  }

.banner.is-not-liked .fa-heart-o{
  display: inline;
  }
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="banner is-liked js-update-heart">
  <i class="fa fa-heart-o"></i>
  <i class="fa fa-heart"></i>
</span>

In this example, the CSS reads nicely, and the jQuery is extremely small.

Erik Philips
  • 53,428
  • 11
  • 128
  • 150