Switching fas fa icon through javascript - Dark / Light mode

Viewed 650

Don't know where I am going wrong, but the icon just doesn't change.

$( ".inner-switch" ).on("click", function() {
    if( $( "body" ).hasClass( "dark" )) {
      $( "nav" ).removeClass( "dark-force" );
      $( "body" ).removeClass( "dark" );
      $(this).find("i").toggleClass("fas fa-moon");
    } else {
      $( "body" ).addClass( "dark" );
      $( "nav" ).addClass( "dark-force" );
      $(this).find("i").toggleClass("fas fa-sun");
    }
});
.dark {
    background-color: #222;
}

.dark-force * {
    background-color: #222;
}
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" />

  <nav class="navbar">
    <div class="hero-body">
      <div class="container">
        <div class="navbar-brand">

          <a href="/">
            <img src="{% static 'portfolio/Logo.png' %}" width=60>
          </a>

          <div class="navbar-end">

            <div class="navbar-item">
              <div class="buttons">
                <a class="button is-primary is-rounded is-outlined">
                  <strong>Blog</strong>
                </a>
              </div>
            </div>

            <div class="navbar-item">
              <div class="buttons">
                <a class="button is-primary is-rounded">
                  <strong>Say Hello!</strong>
                </a>
              </div>
            </div>

            <div class="navbar-item">
              <div class="buttons">
                <a class="button is-primary is-rounded inner-switch">
                  <i class="fas fa-moon"></i>
                </a>
              </div>
            </div>

          </div>
        </div>
      </div>
    </div>
  </nav>

It does switch to dark mode, but the icon refuses to change from the moon(fas fa-moon). I'm new to javascript but fairly familiar with HTML and CSS. Any help is appreciated. Have a great and safe day! Thanks for reading!

3 Answers

You are nearly there and your code looks good but you need to use addClass and removeClass to switch fas fa icon from sun to moon and vice versa.

$(this).find("i").removeClass("fa-sun").addClass('fa-moon');

When you use toggleClass the existing is still there and new icon is not working as it suppose to.

Live Working Demo:

$(".inner-switch").on("click", function() {
  if ($("body").hasClass("dark")) {
    $("nav").removeClass("dark-force");
    $("body").removeClass("dark");
    $(this).find("i").removeClass("fa-sun").addClass('fa-moon');
  } else {
    $("body").addClass("dark");
    $("nav").addClass("dark-force");
    $(this).find("i").removeClass("fa-moon").addClass('fa-sun');
  }
});
.dark {
  background-color: #222;
}

.dark-force * {
  background-color: #222;
}

.fa-sun {
 color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://kit.fontawesome.com/a076d05399.js"></script>
<div class="navbar-item">
  <div class="buttons">
    <a class="button is-primary is-rounded inner-switch is-outlined">
      <i class="fas fa-moon"></i>
    </a>
  </div>
</div>

The problem is that you only toggle the sun and moon class every second time. You need to toggle them both every time!

$(this).find("i").toggleClass("fa-moon").toggleClass("fa-sun");

FYI you don't need to toggle the fas class because you always need it. Also, you don't need to duplicate the code by putting this inside the if/else - as you need to toggle them both every time you click, you can just include this line once directly in the function.

Working example:

$(".inner-switch").on("click", function() {
  // toggle moon and sun every time
  $(this).find("i").toggleClass("fa-moon").toggleClass("fa-sun");

  if ($("body").hasClass("dark")) {
    $("nav").removeClass("dark-force");
    $("body").removeClass("dark");
} else {
 $("body").addClass("dark");
    $("nav").addClass("dark-force");
  }
});
.dark {
  background-color: #222;
}

.dark-force * {
  background-color: #222;
}

.button {
  font-size: 3em;
  color: #f00
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" />

<div class="navbar-item">
  <div class="buttons">
    <a class="button is-primary is-rounded inner-switch is-outlined">
      <i class="fas fa-moon"></i>
    </a>
  </div>
</div>

You also need to toggle the font color when you toggle the background color.

$("#lightswitch i").click(function() {
    var isDark = $("body").is(".dark");
    $("body").toggleClass("dark", !isDark);
    $(this).toggleClass("fa-moon", isDark).toggleClass("fa-sun", !isDark);
});
body.dark {
  background-color: #222;
  color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" />

<body>
  <div class="navbar-item">
    <div class="buttons">
      <a id="lightswitch" class="button is-primary is-rounded inner-switch is-outlined">
        <i class="fas fa-moon"></i>
       </a>
     </div>
  </div>
</body>

Related