简体   繁体   中英

Why is classList.remove is not working but jQuery .removeClass is?

I'm still getting used to plain JavaScript and creating a basic set of square shaped divs that will add and remove classes when clicked. I'm using an array that will add a specific one of those classes. When clicking, I'd like to remove all of those classes before adding a new one. So for example, when clicking on the 2nd square, 'classB' will be added to only that one and then clicking any others will remove it.

I understand that classList.remove has to be before classList.add but for some reason it is not working. I always get the message "Cannot read property 'remove' of undefined at HTMLDivElement.elem.addEventListener".

However, if I use jQuery . removeClass it works with no problem. But I'd prefer not to use jQuery.

Here's the snippet. You can see the classList.remove that I was trying in what's commented out.

 const addClass = ['classA','classB','classC','classD']; const numbers = [0,1,2,3]; const square = document.querySelectorAll('.square'); square.forEach((elem, i) => { elem.addEventListener('click', () => { //square[i].classList.remove(...addClass) $(square).removeClass('classA classB classC classD'); if (i == numbers[i]) { elem.classList.add(addClass[i]); } }); }); 
 .square { width: 2rem; height: 2rem; background-color: black; margin: 1rem; } .classA { background-color: red; } .classB { background-color: yellow; } .classC { background-color: green; } .classD { background-color: blue; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="container"> <div class="square"></div> <div class="square"></div> <div class="square"></div> <div class="square"></div> </div> 

I've looked through a bunch of other questions in here and on other sites but am not really seeing it.

The 2 methods you are comparing are not equivalent:

square[i].classList.remove(...addClass)

Will remove all of the classes in the array from one element.

$(square).removeClass('classA classB classC classD');

Will remove all of those classes from all the squares.

To do this without jQuery you could do:

square.forEach(elem => elem.classList.remove(...addClass));

 const addClass = ['classA','classB','classC','classD']; const numbers = [0,1,2,3]; const squares = document.querySelectorAll('.square'); // renamed square to squares so it's more obvious that it is a NodeList and not a single Node squares.forEach((elem, i) => { elem.addEventListener('click', () => { squares.forEach(elem => elem.classList.remove(...addClass)); if (i == numbers[i]) { elem.classList.add(addClass[i]); } }); }); 
 .square { width: 2rem; height: 2rem; background-color: black; margin: 1rem; } .classA { background-color: red; } .classB { background-color: yellow; } .classC { background-color: green; } .classD { background-color: blue; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="container"> <div class="square"></div> <div class="square"></div> <div class="square"></div> <div class="square"></div> </div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM