Home > Software design >  classList.remove and .add not working for some reason
classList.remove and .add not working for some reason

Time:12-18

When toggling the switch I get these errors from the browser console. For some reason it does not work and I can't solve why this won't work I am just starting Javascript so don't me mad at me if I did something stupid.

Uncaught TypeError: Cannot read properties of undefined (reading 'remove')
    at getValue (darkModeSwitch.js:8)
    at window.onload (index.html:17)

Uncaught TypeError: Cannot read properties of undefined (reading 'add')
    at getValue (darkModeSwitch.js:13)
    at HTMLInputElement.onclick (index.html:26)

HTML:

<div>
        <ul>
            <li><a href="kapcsolat/kapcsolat.html?version=691">Kapcsolat</a></li>
            <li><a href="projects/projects.html?version=691">Projektek</li>
            <li><a  href="index.html?version=692">Kezdőlap</a></li>
            <li><label ><input onclick="getValue()" id="darkModeToggle" type="checkbox" checked><span ></span></label><script src="scripts/darkModeSwitch.js"></script>
            </li>
            <h1  style="float: left;"><a  href="index.html?version=-23424893215">jayden.hu</a></h1>  
        </ul>
    </div>

CSS:

      .lightmode{
    background-color: white;
    color: black;
}

Javascript:

const body = document.body
const anchor = document.getElementsByTagName("a");
const darkModeToggle = document.getElementById('darkModeToggle');

function getValue(){
if (darkModeToggle.checked) {
    body.classList.remove("lightmode")
    anchor.classList.remove("lightmode")
    console.log("checked")
} else{
    console.log("not checked")
    body.classList.add("lightmode")
    anchor.classList.add("lightmode")
}
};

CodePudding user response:

The error is because you're trying to modify the classList on multiple elements at once; your anchor variable contains an array of HTML elements (all of the anchors) rather than one specific element.

Thankfully, because CSS cascades, you don't need to change the class on any elements aside from your body. Just address the a elements like this in CSS so they inherit the body's color:

function getValue() {
  document.body.classList.toggle("lightmode")
};
body {
  background-color: black;
  color: white;
}

.lightmode {
  background-color: white;
  color: black;
}

a {
  color: inherit;
}
<body>
  <ul>
    <li><a href="kapcsolat/kapcsolat.html?version=691">Kapcsolat</a></li>
    <li><a href="projects/projects.html?version=691">Projektek</a></li>
    <li><a  href="index.html?version=692">Kezdőlap</a></li>
    <li><label ><input onclick="getValue()" id="darkModeToggle" type="checkbox" checked><span ></span></label></li>
    <h1  style="float: left;"><a  href="index.html?version=-23424893215">jayden.hu</a></h1>
  </ul>
</body>

CodePudding user response:

The problem is not with Body but with anchor . You use getElementsByTagName which returns a List ( array ) and not a single element even though you have a single a the anchor constant value will be an array with length 1.

Either use querySelector either by ID either select first item document.getElementsByTagName("a")[0] -> not really best practice.

Or, if you have multiple anchor tags, just loop over them

See below

const body = document.body
const anchor = document.querySelectorAll("a.jayden");
const darkModeToggle = document.getElementById('darkModeToggle');

function getValue() {
  if (darkModeToggle.checked) {
    body.classList.remove("lightmode")
    anchor.forEach(a => a.classList.remove("lightmode"))
    console.log("checked")
  } else {
    console.log("not checked")
    body.classList.add("lightmode")
     anchor.forEach(a => a.classList.add("lightmode"))
  }
};
.lightmode {
  background:blue
  }
  a.lightmode {
    color: white
    }
<input onclick="getValue()" id="darkModeToggle" type="checkbox" checked />
<a  href="#" >jayden.hu</a>
<a  href="#" >jayden.hu</a>

CodePudding user response:

Anchor is an HTML collection which should be looped through:

const body = document.body;

const anchor = document.getElementsByTagName('a');
const darkModeToggle = document.getElementById('darkModeToggle');

function getValue(){
 
if (darkModeToggle.checked) {

    console.log("checked");
    if(body.classList.contains("lightmode")){
    body.classList.remove("lightmode")
    }
   for(var a=0;a<anchor.length;a  ){
    if(anchor[a].classList.contains("lightmode")){
    anchor[a].classList.remove("lightmode");
    }
   }
    
} else{

    
    console.log("not checked");
     if(!body.classList.contains("lightmode")){
    body.classList.add("lightmode")
   }
    for(var a=0;a<anchor.length;a  ){
    if(!anchor[a].classList.contains("lightmode")){
    anchor[a].classList.add("lightmode");
    }
   }
}
}
  .lightmode{
    background-color: white;
    color: black;
}
<body>
<div>
        <ul>
            <li><a href="kapcsolat/kapcsolat.html?version=691">Kapcsolat</a></li>
            <li><a href="projects/projects.html?version=691">Projektek</a></li>
            <li><a  href="index.html?version=692">Kezdőlap</a></li>
            <li><label ><input onclick="getValue()" id="darkModeToggle" type="checkbox" checked><span ></span></label><script src="scripts/darkModeSwitch.js"></script>
            </li>
            <h1  style="float: left;"><a  href="index.html?version=-23424893215">jayden.hu</a></h1>  
        </ul>
    </div>
    </body>

CodePudding user response:

<input onclick="getValue()" id="darkModeToggle" type="checkbox" checked />
<a  href="#" >jayden.hu</a>
<a  href="#" >jayden.hu</a>


//Make sure the elements exist on page
const body = document.body
const anchors = document.getElementsByTagName('a');
const darkModeToggle = document.getElementById('darkModeToggle');
    
const getValue = () => {
  body.classList.toggle('lightmode'); // adds or removes class
  for (const anchor in anchors) {
    anchor.classList.toggle('lightmode'); // adds or removes class
  }
};
  • Related