caiq
caiq

Reputation: 35

Adding class to each element with an ID in foreach loop

Hello :) I'm coding dark mode switch and I came across a problem I can't figure out.

I loop through an array which contains items looking like that: { className: 'h3dark', elementId: 'h2'}. Then I use forEach loop to apply each class to ALL elements with a defined ID. Unfortunately it's applying each class on only first html element with an ID. Do you know how it can be fixed?

HTML

<h1 id="h1" class="h1">COLOR</h1>   <!--Color changed-->
<h1 id="h2" class="h1">COLOR</h1>   <!--Color changed-->
<h1 id="h3" class="h1">COLOR</h1>   <!--Color changed-->
<h1 id="h1" class="h1">COLOR</h1>   <!--Color not changed-->
<h1 id="h2" class="h1">COLOR</h1>   <!--Color not changed-->
<h1 id="h3" class="h1">COLOR</h1>   <!--Color not changed-->
    
<button onclick="darkSwitch()">CHANGE COLOR</button>

</div>

JAVASCRIPT

// checking if cookie exists
var cookieState = Cookies.get('darkMode');

// First visit - cookieState is undefined
// If cookie exists we are parsing it to get a boolean
if(cookieState === undefined) {
  var isDarkmodeEnabled = false;
} else {
  var isDarkmodeEnabled = JSON.parse(cookieState)
};

// Cookie doesn't exist: darkMode = false 
// Cookie exists: darkMode = true/false
var darkMode = isDarkmodeEnabled;

// Add dark mode classes and elements' ids
// className - a name of a class with dark mode attributes 
// elementId - an id of an element a class will be added to
var darkClasses = [
  { className: 'h1dark', elementId: 'h1'},
  { className: 'h2dark', elementId: 'h3'},
  { className: 'h3dark', elementId: 'h2'},           
];


// Adding classes on page load if darkmode is enabled
window.onload = addClassesOnLoad();

// Changing darkMode state and adding or removing classes
function darkSwitch() {

  // Setting darkMode to its opposite value
  darkMode = !darkMode;

  if(darkMode === true) {
    // Looping through an array and deleting classes
    darkClasses.forEach(item => {
        document.getElementById(item.elementId).classList.add(item.className)
    });
  } else {
  // Looping through an array and deleting classes
    darkClasses.forEach(item => {
      document.getElementById(item.elementId).classList.remove(item.className)
    });  
  };
  // Saving darkMode state to the cookie
  Cookies.set('darkMode', darkMode);
}

// Adding classes on page load if darkmode is enabled
function addClassesOnLoad() {

  if(darkMode === true){
            
    darkClasses.forEach(item =>{ 
                document.getElementById(item.elementId).classList.add(item.className)
    });
  };
}

That's how it looks like and how it should

Upvotes: 2

Views: 2303

Answers (2)

caiq
caiq

Reputation: 35

Thanks to Nikola Pavicevic's answer I figured it out.

darkClasses.forEach(item => {
    document.getElementById(item.elementId).classList.add(item.className)
});

Changed to:

darkClasses.forEach(item => {
    var element = document.querySelectorAll(`.${item.defaultClass}`)
    element.forEach(h => h.classList.add(item.newDarkClass))
});

and

var darkClasses = [
        { newDarkClass: 'h1dark', defaultClass: 'h1'},
        { newDarkClass: 'h2dark', defaultClass: 'h2'},
        { newDarkClass: 'h3dark', defaultClass: 'h3'},           
    ];


    <h1 class="h1">COLOR</h1>   <!--Color changed-->
    <h1 class="h2">COLOR</h1>   <!--Color changed-->
    <h1 class="h3">COLOR</h1>   <!--Color changed-->
    <h1 class="h1">COLOR</h1>   <!--Color changed-->
    <h1 class="h2">COLOR</h1>   <!--Color changed-->
    <h1 class="h3">COLOR</h1>   <!--Color changed-->

Upvotes: 1

Nikola Pavicevic
Nikola Pavicevic

Reputation: 23490

Try like following snippet:

/*const cookieState = Cookies.get('darkMode');
if(cookieState === undefined){
    let isDarkmodeEnabled = false;
}else{
    let isDarkmodeEnabled = JSON.parse(cookieState)
};
let darkMode = isDarkmodeEnabled;*/
let darkMode = true //replace with isDarkmodeEnabled

const darkClasses = [
    { className: 'h1dark', classId: 'h1'},
    { className: 'h2dark', classId: 'h2'},
    { className: 'h3dark', classId: 'h3'},           
];

toggleDarkMode()

function darkSwitch(){
  darkMode = !darkMode;
  toggleDarkMode()
  //Cookies.set('darkMode', darkMode);
}

function toggleDarkMode(){
  darkClasses.forEach(item => { 
    const h1s = document.querySelectorAll(`.${item.classId}`)
    h1s.forEach(h => h.classList.toggle(item.className))
  })
}
.h1dark {
  color: orange;
}
.h2dark {
  color: red;
}
.h3dark {
  color: violet;
}
<h1 id="1" class="h1">COLOR</h1>   
<h1 id="2" class="h2">COLOR</h1>  
<h1 id="3" class="h3">COLOR</h1>  
<h1 id="4" class="h1">COLOR</h1>  
<h1 id="5" class="h2">COLOR</h1>   
<h1 id="6" class="h3">COLOR</h1>   

<button onclick="darkSwitch()">CHANGE COLOR</button>

Upvotes: 1

Related Questions