switching the content of an element using Javascript

I'd like to switch between two icons when clicking on .switch and apply the style of .nightTextNight to .nightText, my JavaScript code is working well everywhere except here.

Is there a simpler way to achieve this? I currently have to create two classes and give them an ID for every small change.

var nightBtn = document.getElementById("switch");
var body = document.getElementById("body");
var header = document.getElementById("header");
var navbar = document.getElementById("navbar");
var nightText = document.getElementById("nightText");

function nightMode() {
nightBtn.classList.toggle("switchNight");
body.classList.toggle("night");
navbar.classList.toggle("navbarNight");
nightText.classList.toggle("nightTextNight");
if(nightText.className = "nightTextNight") {
nightText.innerHTML = "<i class='fa fa-sun-o' aria-hidden='true'></i>";
} else {
nightText.innerHTML = "<i class='fa fa-moon-o' aria-hidden='true'></i>";
};
}
body {
background-color: white;
transition: background-color ease 0.3s;
padding: 0;
margin: 0;
font-family: sans-serif;
}

.night {
background-color: #3f4b5e;
transition: background-color ease 1s;
}

.switch {
height: 35px;
width: 35px;
border-radius: 50%;
background-color: #092d30;
border: 3px solid wheat;
float: right;
z-index: 4;
transition: background-color ease 1s;
margin-top: 12px;
margin-right: 4px;
cursor: pointer;
text-align: center;
line-height: 17.5px;
position: relative;
}

.switchNight {
background-color: wheat;
border: 3px solid #092d30;
z-index: 4;
transition: background-color ease 1s;
}

.textNight {
color: white;
}

.switch:hover {
background-color: #4d5e77;
transition: background-color ease 1s;
}

.switchNight:hover {
background-color: #fff2d8;
transition: background-color ease 1s;
}

/* --------------------- NAV BAR ------------------ */

.navbar {
width: 100%;
height: auto;
background: #f4f7f9;
position: fixed;
margin-top: 0;
padding: 0;
border-bottom: 3px solid #2fb3f9;
}

.navbar li {
list-style-type: none;
display: inline;
height: auto;
}

.navbar li a {
padding: 20px 25px;
text-decoration: none;
display: inline-block;
font-size: 20px;
font-weight: bolder;
color: #516f7f;
}

.navbar li a:hover {
color: #ff9d00;
transition: color ease 0.3s;
}

.navbarNight {
background-color: #556bb5;
border-bottom: 3px solid white;
}

.navbarNight li a {
color: white;
}

.nightText {
position: absolute;
color: white;
font-weight: bolder;
top: 9px;
right: 12px;
}

.nightTextNight {
color: black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css">
<title>Night Mode - TEST</title>
</head>
<body id="body">
<div id="container">
<div id="nav">
<ul id="navbar" class="navbar">
<li><a href="#">Home</a></li>
<li><a href="#">About me</a></li>
<li><div id="switch" class="switch" onclick="nightMode()"><span id="nightText" class="nightText"><i class="fa fa-moon-o" aria-hidden="true"></i></span></div></li>
</ul>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

Answer №1

It was not functioning correctly due to the presence of two classes:

nightText nightTextNight

To address this issue, you should verify:

if(nightText.className === "nightText nightTextNight")

var nightBtn = document.getElementById("switch");
var body = document.getElementById("body");
var header = document.getElementById("header");
var navbar = document.getElementById("navbar");
var nightText = document.getElementById("nightText");

function nightMode() {
nightBtn.classList.toggle("switchNight");
body.classList.toggle("night");
navbar.classList.toggle("navbarNight");
nightText.classList.toggle("nightTextNight");
if(nightText.className === "nightText nightTextNight") {
nightText.innerHTML = "<i class='fa fa-sun-o' aria-hidden='true'></i>";
} else {
nightText.innerHTML = "<i class='fa fa-moon-o' aria-hidden='true'></i>";
};
  console.log(nightText.className);
}
body {
background-color: white;
transition: background-color ease 0.3s;
padding: 0;
margin: 0;
font-family: sans-serif;
}

.night {
background-color: #3f4b5e;
transition: background-color ease 1s;
}

.switch {
height: 35px;
width: 35px;
border-radius: 50%;
background-color: #092d30;
border: 3px solid wheat;
float: right;
z-index: 4;
transition: background-color ease 1s;
margin-top: 12px;
margin-right: 4px;
cursor: pointer;
text-align: center;
line-height: 17.5px;
position: relative;
}

.switchNight {
background-color: wheat;
border: 3px solid #092d30;
z-index: 4;
transition: background-color ease 1s;
}

.textNight {
color: white;
}

.switch:hover {
background-color: #4d5e77;
transition: background-color ease 1s;
}

.switchNight:hover {
background-color: #fff2d8;
transition: background-color ease 1s;
}

/* --------------------- NAV BAR ------------------ */

.navbar {
width: 100%;
height: auto;
background: #f4f7f9;
position: fixed;
margin-top: 0;
padding: 0;
border-bottom: 3px solid #2fb3f9;
}

.navbar li {
list-style-type: none;
display: inline;
height: auto;
}

.navbar li a {
padding: 20px 25px;
text-decoration: none;
display: inline-block;
font-size: 20px;
font-weight: bolder;
color: #516f7f;
}

.navbar li a:hover {
color: #ff9d00;
transition: color ease 0.3s;
}

.navbarNight {
background-color: #556bb5;
border-bottom: 3px solid white;
}

.navbarNight li a {
color: white;
}

.nightText {
position: absolute;
color: white;
font-weight: bolder;
top: 9px;
right: 12px;
}

.nightTextNight {
color: black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css">
<title>Night Mode - TEST</title>
</head>
<body id="body">
<div id="container">
<div id="nav">
<ul id="navbar" class="navbar">
<li><a href="#">Home</a></li>
<li><a href="#">About me</a></li>
<li><div id="switch" class="switch" onclick="nightMode()"><span id="nightText" class="nightText"><i class="fa fa-moon-o" aria-hidden="true"></i></span></div></li>
</ul>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

Note: I included

console.log(nightText.className);
for displaying the classes; feel free to remove it.

Answer №2

To easily switch between day and night mode, simply toggle the icon class instead of altering the entire i tag.

var sunBtn = document.getElementById("toggle");
var sunBtnIcon = document.getElementById("toggle-icon");
var body = document.getElementById("body");
var header = document.getElementById("header");
var navigation = document.getElementById("navigation");

function toggleMode() {
    sunBtn.classList.toggle("toggleSun");
    body.classList.toggle("day");
    navigation.classList.toggle("navigationNight");
    sunBtnIcon.classList.toggle("fa-sun-o");
    sunBtnIcon.classList.toggle("fa-moon-o");
}

HTML:

<ul id="navigation" class="navigation">
                <li><a href="#">Home</a></li>
                <li><a href="#">About me</a></li>
                <li><div id="toggle" class="toggle" onclick="toggleMode()"><i class="icon fa fa-moon-o" aria-hidden="true" id=“toggle-icon”></i></span></div></li>
            </ul>

Answer №3

One suggestion could be to group all elements that might have a unique style for nighttime in a div or even the body, and then simply apply a "night" class to that wrapper.

This way, you can customize the styles of your elements with ease:


.night .navbar {
  ... night-specific style adjustments ...
}

With this approach, toggling between day and night modes would involve adding or removing the class from the wrapping element. Any new classes added would only affect specific properties that needed changing on those elements.

Answer №4

To effectively disregard the id, utilize an Attribute and use a loop, such as data-mode. See the example below:

var modes={
day:{
      switch:"switch", body:"day", navbar:"navbar",icon:"fa fa-moon-o"
},
night:{
      switch:"switchNight switch", body:"night day", navbar:"navbarNight navbar",icon:"fa fa-sun-o"
   }
}
function changeMode(arg){
window.mode=arg;
var elem=document.querySelectorAll('[data-mode]');
for (var i=0; i<elem.length; i++){
var key=elem[i].getAttribute("data-mode");
elem[i].classList=modes[arg][key];
}

}
window.mode="day";
body {
background-color: white;
transition: background-color ease 0.3s;
padding: 0;
margin: 0;
font-family: sans-serif;
}

.night {
background-color: #3f4b5e;
transition: background-color ease 1s;
}

.switch {
height: 35px;
width: 35px;
border-radius: 50%;
background-color: #092d30;
border: 3px solid wheat;
float: right;
z-index: 4;
transition: background-color ease 1s;
margin-top: 12px;
margin-right: 4px;
cursor: pointer;
text-align: center;
line-height: 17.5px;
position: relative;
}

.switchNight {
background-color: wheat;
border: 3px solid #092d30;
z-index: 4;
transition: background-color ease 1s;
}

.textNight {
color: white;
}

.switch:hover {
background-color: #4d5e77;
transition: background-color ease 1s;
}

.switchNight:hover {
background-color: #fff2d8;
transition: background-color ease 1s;
}

/* --------------------- NAV BAR ------------------ */

.navbar {
width: 100%;
height: auto;
background: #f4f7f9;
position: fixed;
margin-top: 0;
padding: 0;
border-bottom: 3px solid #2fb3f9;
}

.navbar li {
list-style-type: none;
display: inline;
height: auto;
}

.navbar li a {
padding: 20px 25px;
text-decoration: none;
display: inline-block;
font-size: 20px;
font-weight: bolder;
color: #516f7f;
}

.navbar li a:hover {
color: #ff9d00;
transition: color ease 0.3s;
}

.navbarNight {
background-color: #556bb5;
border-bottom: 3px solid white;
}

.navbarNight li a {
color: white;
}

.nightText {
position: absolute;
color: white;
font-weight: bolder;
top: 9px;
right: 12px;
}

.nightTextNight {
color: black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8>;
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css">
<title>Night Mode - TEST</title>
</head>
<body data-mode="body">
<div>
<div>
<ul class="navbar" data-mode="navbar">
<li><a href="#">Home</a></li>
<li><a href="#">About me</a></li>
<li><div class="switch" data-mode="switch" onclick="changeMode(mode=='night'?'day':'night');">
<span class="nightText">
<i class="fa fa-moon-o" data-mode="icon"></i>
</span>
</div>
</li>
</ul>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

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

What method is used to initialize the variables in this JavaScript snippet, and what other inquiries are posed?

As a backend developer, I'm looking to understand this JavaScript snippet. While I grasp some parts and have added comments where I am clear, there are still sections that leave me with bold questions. function transformData (output) { // QUESTIO ...

Add two columns for mobile devices in the Woocommerce platform

How can I display 2 columns of products in my Woocommerce shop using a child theme based on 'Shopisle'? Is a CSS-only solution the best approach for this task, and will it work smoothly without any bugs? I suspect that the theme is built on Boot ...

Locating a record within a database that contains an objectId field linking to a separate collection

I have defined two collections in the following manner const BookSchema = new mongoose.Schema({ title: String, author: { type: mongoose.Object.Types.ObjectId, ref: "author" } }) const BookModel = mongoose.model(" ...

Encountered an error while trying to run npm start

I set up a Vagrant virtual machine, installed Node.js (v 6.9.1), and NPM (v 4.0.0). After cloning a Node.js app using Git clone, I ran the npm install command in both the root folder and the app folder. However, when attempting to start the app with npm st ...

Is it possible to utilize the map method to extract objects that are nested multiple layers deep?

I am working on accessing the change order information in order to compile a list of all the change_order_names. The code I am currently using is yielding the results displayed below. Could someone assist me in understanding how to access the change order ...

Is it possible for a JSON array to consist of objects with varying key/value pairs?

Is it possible for a JSON array to contain objects with different key/value pairs? The example provided in this tutorial shows objects within the JSON array having the same key/value pair: { "example": [ { "firstName": " ...

Unable to fetch data in CakePHP 3.x controller using jQuery AJAX POST

I've been searching everywhere and unfortunately, I can't seem to figure out why the data is not being sent to my controller when posting via ajax. Here's the jQuery code snippet: var newDate = {}; newDate['start' ...

The canvas appears blank when using Firefox version 36

The application is made up of an interface (html) and workspace (canvas). We utilize three.js to create elements on the canvas. So far, it's been functioning perfectly on Chrome, Opera, and Firefox 35. You can see it in action here: However, in Firef ...

Please ensure that the menu is included within the HTML file

How can I include a menu from menu.html into index.html? The content of menu.html is: <li><a href="home.html">Home</a></li> <li><a href="news.html">News</a></li> In index.html, the code is: <!docty ...

Has the default underline in Bootstrap 5 been altered?

When working with Bootstrap 4, I noticed that it sets the default text-decoration to be none. However, in Bootstrap 5, just adding a regular anchor tag results in both blue text and an underline being displayed. I was trying to achieve only showing the u ...

Is it true that setting the background size to cover does not actually stretch the image?

Hi, I seem to be having trouble stretching an image using the background-size property. Despite setting it to cover, one or two sides of the image are always getting cropped. What I really want is a way to distort the image so that it stretches to fit any ...

Submitting values using the serialize method and Ajax involves sending placeholders

Looking for a solution: <form class="pure-form pure-form-stacked" method="post" enctype="multipart/form-data"> <input type="text" name="name" class="button-size-1" placeholder="*Name"> <input type="text" name="email" class="but ...

Discovering the culprit causing a freeze on your page: Uncovering the tool or technique to identify the problematic

What is the best tool to identify resource-heavy or infinite loop JavaScript/jQuery scripts? I am currently experiencing issues with a specific template: When I open this page on Firefox 46.0.1, it freezes after a few minutes. I am having trouble pinpoin ...

Establishing foreignObject coordinates in Angular

Struggling with setting the position (x, y) for foreignObject in Angular. I have attempted the following: <foreignObject width="65" height="50" x="{{position?.x}}" y="{{position?.y}}"> <div class="c ...

Is there a way to incorporate multiple rules from data into a text component using Vuetify?

I'm looking to establish specific rules within a mixin for my components. Allow me to provide a straightforward example of my request: Example Link The code snippet: <v-text-field :rules="[nbRules, requiredRules]" outlined v-model="name" label ...

The page fails to load when redirected, however, it briefly displays the page upon clicking the back button before navigating back to the previous page

Currently, I am working with Angular 2 and encountering an issue when attempting to click on a link. The loading bar continues to progress without displaying the data or HTML content on the page. Furthermore, if I try to go back to the previous page, the i ...

What could be causing my carousel slider images to not adapt to different screen sizes?

I recently added a carousel slider to my website, and while it looks great on larger screens like desktops and laptops, I noticed that the images are not scaling properly when viewed on smaller screen widths. This has resulted in non-responsiveness which i ...

How do I change the class of an element using $this?

Please review the code below: $(".nwe-cl-icontext").click(function () { $(this).parent().toggleClass("nwe-active"); }) .nwe-cl-c.nwe-active { background: red; } .nwe-cl-c { background: green; } <scrip ...

Words hovering in a section next to a captivating picture

I am looking to achieve a specific arrangement: I want two different texts (in block format) to float or display inline next to an image, all within a div element. Despite trying various display settings (such as block and inline for text), I have not be ...

What techniques can be applied to utilize JSON data in order to dynamically create menu components using the map method?

My current challenge involves dynamically generating a set of menu items using data retrieved from a JSON file. I've attempted to achieve this by mapping the values with props, but it seems like I'm overlooking something. Below is the code snipp ...