HTML Academy
Introduction to classList.toggle
Introduction to JavaScript11/17
Back to the list of tasks
  • 1. Why is JavaScript necessary?
  • 2. Introduction to the theme switcher
  • 3. Find an element using querySelector
  • 4. Output the element to the console.
  • 5. Let’s remove the class using classList.remove
  • 6. Let’s add a class to the element using classList.add
  • 7. Declare a variable
  • 8. Introduction to the event handler
  • 9. Let’s make it so that the theme is switched when the button is clicked
  • 10. Introduction to classList.toggle
  • 11. Let’s finish our theme switcher
  • 12. Introduction to the textContent property
  • 13. Change the textual content for the element
  • 14. Uncomment the code
  • 15. We retrieve data from the input field using input.value
  • 16. Let’s use concatenation
  • 17. Summary of “Introduction to JavaScript”
Introduction to the textContent property
  • Sign up
  • Log in

Loading…
Everything will be ready in few seconds

  • Theory
  • Theory
  • Comments

Let’s finish our theme switcher

We wrote an instruction that removes the light-theme class from an element if it exists and adds it if it does not exist. By doing this, when we click on the “Change Theme” button, the light theme is disabled and enabled alternatively on the page. But what about the dark theme? After all, we need to make sure that the themes switch back and forth with each other. In order to do this, we need to make sure that the light-theme and dark-theme classes alternate with each other in the body element: first one is added and the other is deleted, and then vice-versa. How are we able to do that?

We need to write a second instruction with classList.toggle. It will both add and delete the dark-theme class when the button is clicked. To ensure that the themes alternate with each other, the instructions must work in reverse. To do this, one theme class must be specified while the other one is not in the source markup for the body element. In that case one class is deleted, and the other, on the other hand, is added to the element.

The light-theme class exists for the page element in index.html. Here’s what happens when we first click on the “Change Theme” button:

<!-- Source markup -->
<body class="page light-theme">
  …
</body>

<!-- Markup in the browser after classList.toggle('light-theme') -->
<body class="page">
  …
</body>

<!-- Markup in the browser after classList.toggle('dark-theme') -->
<body class="page dark-theme">
  …
</body>

When the user clicks the button a second time, the first instruction will add the light-theme class and the second removes the dark-theme class. An odd number of clicks will have the same effect as one click, and an even number of clicks has the same effect as two clicks. The user will be able to switch between themes as many times as they like.

Add the second instruction inside the event handler and make sure that when you click on the “Change Theme” button, the themes on the page alternate as intended.

Comments

  • index.html
  • style.css
  • script.js
HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="setting.css"> <link rel="stylesheet" href="style.css"> <title>FlashNews!</title> </head> <body class="page light-theme"> <header class="page-header"> <div class="container"> <a class="header-link" href="#">Main page</a> <button class="theme-button" type="button">Change the theme</button> </div> </header> <main class="inner-main"> <div class="container"> <h1 class="inner-heading">Subscribe to our newsletter</h1> <p class="subscription-message">We promise to send you news no more than once a day. We will only send you the most interesting and important stories.</p> <form action="https://echo.htmlacademy.ru/courses" method="post" class="subscription"> <div class="subscription-inner"> <label class="subscription-label" for="subscription-email">email</label> <input type="email" class="subscription-email" placeholder="muffin@flashnews.ru" value="" required id="subscription-email"> </div> <button class="button subscription-button" type="submit">Subscribe</button> </form> <section class="news-list list-tiles-view"> <h2 class="news-list-heading">Or continue reading more news stories.</h2> <article class="new-block"> <img src="img/new-graph.jpg" alt="New library"> <div class="new-block-text"> <h3>New graphics library</h3> <p>Now you can create a dashboard in just a matter of seconds.</p> <time datetime="2019-10-16">October 16, 2019</time> </div> </article> <article class="new-block"> <img src="img/new-robot.jpg" alt="What is going on with robots?"> <div class="new-block-text"> <h3>What is going on with robots?</h3> <p>A lot of interesting things are happening in robotics. This could be a piece of news about the latest developments, but that is not what this is.</p> <time datetime="2019-10-15">October 15, 2019</time> </div> </article> </section> </div> </main> <footer class="page-footer"> <div class="container"> <p>© FlashNews!</p> <a class="footer-logo"> <img src="img/white-logo.svg" alt="FlashNews! portal logo"> </a> </div> </footer> <script src="script.js"></script> </body> </html>
CSS
/* Light theme */ .light-theme { color: #333333; background-color: #eae9f2; } .light-theme .page-header { background-color: #ffffff; box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2); } .light-theme .header-link { color: #6653d9; } .light-theme .header-link::before { background: url("img/arrow-back-light.svg") no-repeat 0 0; } .light-theme .theme-button { color: #6653d9; border: 1px solid #6653d9; } .light-theme .theme-button::before { background-image: url("img/moon-normal.svg"); } .light-theme .theme-button:focus, .light-theme .theme-button:hover { color: #ffffff; background-color: #6653d9; } .light-theme .theme-button:focus::before, .light-theme .theme-button:hover::before { background-image: url("img/moon-hover.svg"); } .light-theme .menu-open { background-color: #ffffff; background-image: url("img/menu-open-light.svg"); } .light-theme .menu-open:focus, .light-theme .menu-open:hover { background-color: #6653d9; background-image: url("img/menu-open-dark.svg"); } .light-theme .menu-close { background-color: #6653d9; } .light-theme .menu-close:focus, .light-theme .menu-close:hover { background-color: #473c8d; } .light-theme .main-menu { background-color: #6653d9; color: #ffffff; } .light-theme .main-menu a:focus, .light-theme .main-menu a:hover { background-color: #473c8d; } .light-theme .news-view button { border: 1px solid #6653d9; color: #6653d9; } .light-theme .news-view button:focus, .light-theme .news-view button:hover, .light-theme .news-view button:active, .light-theme .news-view .view-checked { background-color: #6653d9; color: #ffffff; } .light-theme .news-view .row-view:focus::before, .light-theme .news-view .row-view:hover::before, .light-theme .news-view .row-view:active::before { background-image: url("img/rows-light-checked.svg"); } .light-theme .news-view .tile-view:focus::before, .light-theme .news-view .tile-view:hover::before, .light-theme .news-view .tile-view:active::before { background-image: url("img/tiles-light-checked.svg"); } .light-theme .row-view::before { background-image: url("img/rows-light.svg"); } .light-theme .tile-view::before { background-image: url("img/tiles-light.svg"); } .light-theme .row-view::before { background-image: url("img/rows-light.svg"); } .light-theme .row-view.view-checked::before { background-image: url("img/rows-light-checked.svg"); } .light-theme .tile-view.view-checked::before { background-image: url("img/tiles-light-checked.svg"); } .light-theme .new-block { background-color: #ffffff; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2); } .light-theme .new-block time { color: #aaaaaa; } .light-theme .cookies-agreement { background-color: #fdeacd; box-shadow: 0 -1px 4px rgba(0, 0, 0, 0.2); } .light-theme .button { background-color: #6653d9; color: #ffffff; } .light-theme .button:focus, .light-theme .button:hover { background-color: #473c8d; } .light-theme .page-footer { background-color: #6653d9; color: #ffffff; } .light-theme .subscription { background-color: #ffffff; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2); } .light-theme .subscription-message { background-color: #6653d9; color: #eae9f2; } .light-theme .subscription-message::before { background-image: url("img/icon-ok-light.svg"); } .light-theme .subscription-label { color: #6653d9; } .light-theme .subscription-email { border-bottom: 1px solid #6653d9; color: #333333; } /* Dark theme */ .dark-theme { color: #f2f2f2; background-color: #17161a; } .dark-theme .page-header { background-color: #373540; box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6); } .dark-theme .header-link { color: #9484f2; } .dark-theme .header-link::before { background: url("img/arrow-back-dark.svg") no-repeat 0 0; } .dark-theme .theme-button { color: #9484f2; border: 1px solid #9484f2; } .dark-theme .theme-button::before { background-image: url("img/sun-normal.svg"); } .dark-theme .theme-button:focus, .dark-theme .theme-button:hover { color: #17161a; background-color: #9484f2; } .dark-theme .theme-button:focus::before, .dark-theme .theme-button:hover::before { background-image: url("img/sun-hover.svg"); } .dark-theme .menu-open { background-color: #373540; background-image: url("img/menu-open-dark.svg"); } .dark-theme .menu-open:focus, .dark-theme .menu-open:hover { background-color: #473c8d; background-image: url("img/menu-open-dark.svg"); } .dark-theme .menu-close { background-color: #473c8d; } .dark-theme .menu-close:focus, .dark-theme .menu-close:hover { background-color: #6653d9; } .dark-theme .main-menu { background-color: #473c8d; color: #f2f2f2; } .dark-theme .main-menu a:focus, .dark-theme .main-menu a:hover { background-color: #6653d9; } .dark-theme .news-view button { border: 1px solid #9484f2; color: #9484f2; } .dark-theme .news-view button:focus, .dark-theme .news-view button:hover, .dark-theme .news-view button:active, .dark-theme .news-view .view-checked { background-color: #9484f2; color: #17161a; } .dark-theme .news-view .row-view:focus::before, .dark-theme .news-view .row-view:hover::before, .dark-theme .news-view .row-view:active::before { background-image: url("img/rows-dark-checked.svg"); } .dark-theme .news-view .tile-view:focus::before, .dark-theme .news-view .tile-view:hover::before, .dark-theme .news-view .tile-view:active::before { background-image: url("img/tiles-dark-checked.svg"); } .dark-theme .row-view::before { background-image: url("img/rows-dark.svg"); } .dark-theme .tile-view::before { background-image: url("img/tiles-dark.svg"); } .dark-theme .row-view.view-checked::before { background-image: url("img/rows-dark-checked.svg"); } .dark-theme .tile-view.view-checked::before { background-image: url("img/tiles-dark-checked.svg"); } .dark-theme .new-block { background-color: #2a2930; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.6); } .dark-theme .new-block time { color: #888888; } .dark-theme .cookies-agreement { background-color: #473c8d; box-shadow: 0 -1px 4px rgba(0, 0, 0, 0.6); } .dark-theme .button { background-color: #9484f2; color: #17161a; } .dark-theme .button:focus, .dark-theme .button:hover { background-color: #b6aaff; } .dark-theme .page-footer { background-color: #0a0910; color: #f2f2f2; } .dark-theme .subscription { background-color: #2a2930; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.6); } .dark-theme .subscription-message { background-color: #9484f2; color: #17161a; } .dark-theme .subscription-message::before { background-image: url("img/icon-ok-dark.svg"); } .dark-theme .subscription-label { color: #9484f2; } .dark-theme .subscription-email { border-bottom: 1px solid #9484f2; color: #f2f2f2; }
JavaScript
let page = document.querySelector('.page'); let themeButton = document.querySelector('.theme-button'); themeButton.onclick = function() { page.classList.toggle('light-theme'); };

What didn’t you like in this task?

Thanks! We’ll fix everything at once!

Click inside the mini browser to put the focus in this window.

100%
Console
Goalscompleted
0
    1. On line 6 write an instruction that will switch the dark-theme class for the page element.
    2. Double click on the “Change Theme” button in the mini-browser.

    Cookies ∙ Privacy ∙ License Agreement ∙ About ∙ Contacts ∙ © HTML Academy OÜ, 2019−2025

    VISAMastercard

    Log in

    or

    Forgot your password?

    Sign up

    Sign up

    or
    Log in

    Restore access

    Have you forgotten your password or lost access to your profile? Enter your email connected to your profile and we will send you a link to restore access.

    Forgot to connect your email to the profile? Email us and we’ll help.