Я все еще привыкаю к простому JavaScript и создаю базовый набор квадратных блоков div, которые будут добавлять и удалять классы при нажатии. Я использую массив, который добавит один из этих классов. При нажатии я хотел бы удалить все эти классы, прежде чем добавлять новый. Так, например, при нажатии на 2-й квадрат «класс B» будет добавлен только к этому, а затем при нажатии на любой другой квадрат он будет удален.
Я понимаю, что classList.remove должно быть раньше classList.add, но почему-то не работает. Я всегда получаю сообщение «Не удается прочитать свойство« удалить »неопределенного в HTMLDivElement.elem.addEventListener».
Однако, если я использую jQuery .removeClass, он работает без проблем. Но я бы предпочел не использовать jQuery.
Вот фрагмент. Вы можете увидеть classList.remove, что я пытался, в том, что закомментировано.
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>Я просмотрел кучу других вопросов здесь и на других сайтах, но на самом деле не вижу этого.
Это потому, что square — это NodeList. Попробуйте this.classList.remove().



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Два метода, которые вы сравниваете, не эквивалентны:
square[i].classList.remove(...addClass)
Удалит все классы в массиве из элемента один.
$(square).removeClass('classA classB classC classD');
Удалит все эти классы из все квадратов.
Чтобы сделать это без jQuery, вы можете сделать:
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>Однако они хотят, чтобы это было внутри события click (я полагаю, исходя из кода).
@EternalHour Да, я обновил свой ответ фрагментом.
Вы уверены, что хотите вызвать
classList.remove()наsquare, а не наelem?