Home > Back-end >  How can I toggle between 2 classes on click on the same element on JS
How can I toggle between 2 classes on click on the same element on JS

Time:12-04

Need your help on something,

Trying to toggle between classes when I click on an element on an HTML page but unfortunately once toggled I cannot change it back.

Even tried returning the querySelector but no luck.

Here is the code I wrote;

let fetchNumbers = document.querySelectorAll(`.cardnumber`);

for (let index = 0; index < fetchNumbers.length; index  ) {

  if (fetchNumbers[index].classList.contains('unselected') === true) {
    fetchNumbers[index].addEventListener(`click`, function() {
      fetchNumbers[index].classList.add(`selected`);
      fetchNumbers[index].classList.remove(`unselected`);
      fetchNumbers = document.querySelectorAll(`.cardnumber`);
      return fetchNumbers;
    });
  } else {
    fetchNumbers[index].addEventListener(`click`, function() {
      fetchNumbers[index].classList.add(`unselected`);
      fetchNumbers[index].classList.remove(`selected`);
      fetchNumbers = document.querySelectorAll(`.cardnumber`)
      return fetchNumbers;
    });
  }
}
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Thank you in advance

CodePudding user response:

Have You tried using the toggle() method? I think that it might be what You're looking for

Give it a shot!

https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_toggle_class

Another example that might be helpful

https://codepen.io/StrengthandFreedom/pen/ZOGVLg

CodePudding user response:

I've created an Asp.NET Core application to test/debug your code with a fresh html page and javascript with your code snippet.

If this code block below is the only code in your Javascript file,

let fetchNumbers = document.querySelectorAll(`.cardnumber`);

for (let index = 0; index < fetchNumbers.length; index  ) {

if (fetchNumbers[index].classList.contains('unselected') === true) {
    fetchNumbers[index].addEventListener(`click`, function () {
        fetchNumbers[index].classList.add(`selected`);
        fetchNumbers[index].classList.remove(`unselected`);
        fetchNumbers = document.querySelectorAll(`.cardnumber`);
        return fetchNumbers;
    }); 
} else {
    fetchNumbers[index].addEventListener(`click`, function () {
        fetchNumbers[index].classList.add(`unselected`);
        fetchNumbers[index].classList.remove(`selected`);
        fetchNumbers = document.querySelectorAll(`.cardnumber`)
        return fetchNumbers;
    }); 
}

Info

Javascript files are loaded statically, which means they are ran immediately after the html page is loaded into the DOM, so this code is run immediately after the html page is loaded.

Problem

Based upon the classes defined by your html elements (in this case - ), once the page loads, your code block above would hit the first if statement, then assign the click event to all cardnumber elements, then proceed to change the class from unselected to selected. When you go to click your html element the second time, the click event from the if block in your if/else block will NOT be ran as the page has already loaded. This means the else block will never execute. This is the reason you are not seeing any functionality on the second click.

note

Javascript events can only be defined once, so you'd never be able to bind both the click events in the if block AND else block.

Solution

Define the click event for your cardnumber. Move your if/else logic into your new click event like below:

let fetchNumbers = document.querySelectorAll('.cardNumber');

for (let index = 0; index < fetchNumbers.length; index  ) {

    fetchNumbers[index].addEventListener('click', function () {
        if (fetchNumbers[index].classList.contains('unselected') === true) {
            fetchNumbers[index].classList.add('selected');
            fetchNumbers[index].classList.remove('unselected');
            fetchNumbers = document.querySelectorAll('.cardNumber');
            return fetchNumbers;
        } else {
            fetchNumbers[index].classList.add('unselected');
            fetchNumbers[index].classList.remove('selected');
            fetchNumbers = document.querySelectorAll('.cardNumber')
            return fetchNumbers;
        }
    });
}
  • Related