Modify button text with javascript based on the body's class selection

I successfully implemented a dark and light theme on my website following this helpful guide. The two color schemes are defined as classes in CSS and dynamically applied to the body element using JavaScript. The script automatically selects the theme based on the user's operating system preference, but users can also manually switch between themes by clicking a button, which then overrides the OS settings. The selected preference is saved locally using localStorage.

As I continue learning JavaScript, I attempted to create a function that changes the text of the theme switch button depending on the currently applied theme:

    if (document.body.classList.contains("dark-theme")) {
      document.getElementById("theme-btn").innerHTML = "Light Mode";
    } else if (document.body.classList.contains("light-theme") {
      document.getElementById("theme-btn").innerHTML = "Dark Mode";
    }
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
</head>
<body class="dark-theme">
  
  <button class="btn-toggle" id="theme-btn">Dark Mode</button>

</body>
</html>

Although this approach seems to be working fine, I am open to suggestions for improvements or alternative methods to achieve the same outcome. Any advice or ideas would be greatly appreciated!

Answer №1

I managed to get things working, but it's not ideal. My solution is a bit messy and still has some issues. Here's what I have so far. The problem with my initial attempt is that both classes, "light-mode" and "dark-mode", exist in the body's classList, but they aren't being "applied"? Without a js-method to determine which class is active, this approach won't work - because both conditions in the if/else statement are always true, leading to the if-clause always being executed.

So...I came up with a simple (yet intricate) set of functions to achieve what I wanted. Essentially, the script checks localStorage to see if a theme has already been saved and applies the appropriate button text. However, the if-else statement is repeated every time the button is clicked (the same if/else clause appears twice in the code, is there a better way to handle this?)

<!DOCTYPE html>
<head>
  <meta charset="utf-8" />
</head>

<body>
  <button class="btn-toggle" id="theme-btn">Change Theme</button>
  <script>
    /* Change "theme-btn".innerHTML based on color theme in localStorage */
    if (localStorage.getItem("theme") == "dark") {
      document.getElementById("theme-btn").innerHTML = "Light Mode";
    } else if (localStorage.getItem("theme") == "light") {
      document.getElementById("theme-btn").innerHTML = "Dark Mode";
    }
    btn.addEventListener("click", function() { /* Listen for Event-change in button and check localStorage for theme change */
      if (localStorage.getItem("theme") == "dark") {
        document.getElementById("theme-btn").innerHTML = "Light Mode";
      } else if (localStorage.getItem("theme") == "light") {
        document.getElementById("theme-btn").innerHTML = "Dark Mode";
      }
    });
  </script>
</body>

Overall, this works well with the rest of my site. The only issue arises when there's no key stored in localStorage yet, as the correct text isn’t applied. Therefore, this solution only functions properly after the button is manually clicked…and doesn't cater to new visitors.

In search of an alternative solution, I thought about checking the OS' preference first before monitoring the button-click. Unfortunately, my attempts were unsuccessful – I will detail what I tried tomorrow.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I'm new to this, but can someone explain why I'm being redirected to the register_db.php page when I click on the register button?

Why when I click the register button, it redirects me to the register_db.php page instead of sending the data to the database and keeping me on the same register.php page? I want the data to be sent to the database without changing the webpage. register.p ...

Prepending a string to the key of a JSON object using JavaScript

Is there a way to add 'd:' before the key of a JSON object? Here is the JSON data: "data": { "aa": "value", "ab": "value" } The expected result should look like this: "d:data": ...

Using jQuery to retrieve the id with [id^=''] when making an AJAX request, then populating and generating a table based on the retrieved data

In my jQuery code, I am using AJAX to fetch data and then creating a simple table with that data. Here is an example: $.ajax({ method: 'GET', url: '/analyzePage/searchTag/' + tagName, contentType: false, processData: fa ...

Finding the distance between two coordinates using Mapbox is easy once you understand how to utilize

Currently, I am in the process of learning how to utilize the Mapbox API within my node application. One of my objectives is to execute calculations on the backend, particularly obtaining the distance between two sets of coordinates. I'm struggling w ...

The Javascript code compiled in Rails 5 is only functioning on the production environment

I have a JavaScript snippet that is supposed to add a specific class to all images within a container with a certain class: $(document).on('turbolinks:load', function() { $('.blog-article img').addClass('img-fluid'); }); Th ...

Is it possible for Django's trans tags to incorporate HTML tags?

Is it possible for Django trans tags to incorporate HTML tags? For instance, can I use {% trans "Hold <em><strong>Ctrl</strong></em>" %}? Or would I need to use {% trans "Hold" %} <em><strong>{% trans "Ctrl" %}</str ...

Issue with AJAX POST request: PHP failing to establish session

I would like to pass the element's id to PHP and create a session for it. This snippet is from a PHP file: <?php $sql = "SELECT id FROM products"; $result = mysqli_query($con,$sql); while($row = mysqli_fetch_array($result)) { ?> <tr cl ...

Modifying a table row in real-time with the power of JQuery/JavaScript

I successfully created a table with a for loop in Java Spring and now I'm trying to dynamically show and hide specific parts of it when a button is clicked. Here's a simplified version of what I have: <jsp:attribute name= "scripts"> ...

the overflow issue with Summernote's dropdown menu

I am currently working on a 2 columns layout within 2 divs that have different margins set. In the left column, I have integrated a bootstrap datetimepicker and summernote. While the datetimepicker dialog overflows outside the internal div, I am wondering ...

Place an element that exceeds 100% in size at the center

How can I center an image that is larger than its parent element? I have set the min-width and min-height to 100% so that the picture will always fill up the parent element. The issue arises when the image does not match the proportions of the parent elem ...

I've managed to mess up my code again; local storage was working fine, and now it's not. I'm completely clueless

I attempted to store the best game times in local storage by creating an empty array called gBestScores. I compared the value of the last best score to the current one and decided whether to push it into the array or not. However, despite my efforts, the ...

Toggle the display of selected options based on the presence of multiple classes within a td element

Upon selecting an option from a dropdown, certain columns are shown while others are hidden. Some columns have multiple classes assigned to them. For instance: "object 7" belongs to "category 1" and "category 3". "objec ...

The Socket.io server is experiencing issues with the "connection" event not firing, and the client event is also not being triggered

I've been struggling to set up an express backend with socket io. No matter what I try, the connection events just won't fire. Both the server and client are using version 3.1.2, so that's not the issue. When I start the client app, I see so ...

Whenever I attempt to search for an element within my useState array, my component automatically re-renders

Currently working on a React project and facing an issue with the search Input. Whenever I type something in the Input field, the entire component re-renders, triggering an API recall and clearing out the text in the Input. Even after merging the search co ...

Shifting around haphazardly positioned crates using the cursor

I've successfully developed a program that fills the canvas with randomly positioned boxes of various colors. While this task was relatively easy, I'm now facing a challenge in moving these colored boxes around using my mouse. Additionally, I wan ...

Is there a way to have the collapsible content automatically expanded upon loading?

I came across a tutorial on w3school (https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_collapsible_symbol), which demonstrates collapsible content hidden by default. The code snippet from the link is provided below. Can someone assist me in cha ...

The Vue plugin encountered an issue with an error message stating "Uncaught SyntaxError: Unexpected token

I'm excited to dive into using vue for my upcoming project. I decided to incorporate Hooper, an image carousel, and went ahead to install it using npm install hooper. To implement it in my script file, I included the following code: import { Hooper ...

Difficulties arise when trying to implement the jQuery SVG animation plugin on a straight line

After digging through the documentation, it seems a bit lacking on this topic and a few things just don't seem to add up, My goal is to make a line follow an animated element by using the same animation variables as those of the box element for the X ...

Utilizing Bootstrap to set a dynamic background image that spans the entire width of a table

The background image on my About page is not displaying correctly. The first < div > in my container shows it as intended, but the second < div > has white bars on the sides of the table. As a newcomer to Bootstrap and HTML, I hesitated to see ...

NodeJS is throwing a `ReferenceError` because the `io` variable is not

I am working on a NodeJS project and I need to access a variable that is defined in my app.js file from another file. Is this possible? Here is my code: app.js var app = express(); var io = require('socket.io').listen(app); ... otherFile ...