Как убирать/добавлять класс при динамическом добавлении контента?
Столкнулся с такой проблемой. Есть определенный контент, при котором при клике я добавляю и удаляю класс active. Весь такой код у меня работает. Но когда я добавляю динамически ещё контент, то класс к нему добавляется, но не удаляется. Подскажите как можно это решить?
CodePen: https://codepen.io/Power2021/pen/qBXQEbK?editors=1010.
const btn = document.querySelector('.btn');
const inputText = document.querySelector('.input-text');
const InputNumber = document.querySelector('.input-number');
const wrap = document.querySelector('.wrap');
const wrapItem = document.querySelectorAll('.wrap__item');
// Создаём элементы
btn.addEventListener('click', () => {
const inputTextValue = inputText.value;
const InputNumberValue = InputNumber.value;
let item = `
<div class="wrap__item">
<div class="wrap__item-name">${inputTextValue}</div>
<div class="wrap__item-cena">${InputNumberValue}</div>
</div>
`
wrap.insertAdjacentHTML('beforeend', item);
})
// Добавление/Удаление active
wrap.addEventListener('click', (e) => {
const target = e.target;
const targetItem = target.closest('.wrap__item');
if (targetItem) {
for (let i = 0; i < wrapItem.length; i++) {
wrapItem[i].classList.remove('active');
}
target.closest('.wrap__item').classList.add('active');
}
});
* {
margin: 0;
padding: 0;
}
.container {
max-width: 900px;
margin: 0 auto;
padding: 0 15px;
}
.add {
border: 2px solid #000;
margin-top: 20px;
padding: 20px;
}
.wrap {
margin-top: 20px;
}
.wrap__item {
max-width: 100px;
position: relative;
cursor: pointer;
}
.wrap__item:not(:last-child) {
margin-bottom: 20px;
}
.wrap__item.active::before {
content: "";
width: 10px;
height: 10px;
border-radius: 100%;
background-color: #000;
position: absolute;
top: 50%;
right: 0;
}
<div class="container">
<div class="add">
<h1>Добавляем что-то</h1>
<input class="input input-text" type="text" placeholder="Названия">
<input class="input input-number" type="number" placeholder="Цена">
<button class="btn">Добавить</button>
</div>
<div class="wrap">
<div class="wrap__item active">
<div class="wrap__item-name">Пункт</div>
<div class="wrap__item-cena">22</div>
</div>
<div class="wrap__item">
<div class="wrap__item-name">Пункт</div>
<div class="wrap__item-cena">555</div>
</div>
<div class="wrap__item">
<div class="wrap__item-name">Пункт</div>
<div class="wrap__item-cena">22222</div>
</div>
</div>
</div>
Ответы (2 шт):
Автор решения: Igor
→ Ссылка
//const wrapItem = document.querySelectorAll('.wrap__item');
...
wrap.addEventListener('click', (e) => {
const target = e.target;
const targetItem = target.closest('.wrap__item');
if (targetItem) {
const wrapItem = document.querySelectorAll('.wrap__item'); // <---
for (let i = 0; i < wrapItem.length; i++) {
wrapItem[i].classList.remove('active');
}
target.closest('.wrap__item').classList.add('active');
}
});
Автор решения: Михаил Камахин
→ Ссылка
Вообще можно было бы сделать по другому, добавлять новые input type="radio" и не нужно будет писать некоторую логику, которая есть у radio кнопок.
Я переписал ваш код на класс, может что-то интересное увидите у меня
class Wrap {
wrapItemCollection = [];
wrapNode = null;
constructor({
initialWrapItems,
selectorWrap,
selectorForm,
selectorInputText,
selectorInputNumber,
selectorWrapItem
}) {
const form = document.querySelector(selectorForm);
const inputTextNode = form.querySelector(selectorInputText);
const inputNumberNode = form.querySelector(selectorInputNumber);
this.wrapNode = document.querySelector(selectorWrap);
this.createContentInWrapNode(initialWrapItems, this.wrapNode);
this.addEventListenerForm(form, inputTextNode, inputNumberNode);
}
addEventListenerForm(form, inputTextNode, inputNumberNode) {
form.addEventListener("submit", (event) => {
event.preventDefault();
const inputTextValue = inputTextNode.value;
const InputNumberValue = inputNumberNode.value;
const wrapItemNode = this.createWrapItemNode({
name: inputTextValue,
price: Number(InputNumberValue)
});
this.insertWrapItemIntoWrap(wrapItemNode, this.wrapNode);
this.addEventListenerForWrapItem(wrapItemNode);
});
}
createContentInWrapNode(initialWrapItems, wrapNode) {
for (const wrapItemObj of initialWrapItems) {
const wrapItemNode = this.createWrapItemNode(wrapItemObj);
this.insertWrapItemIntoWrap(wrapItemNode, wrapNode);
this.addEventListenerForWrapItem(wrapItemNode);
}
}
createWrapItemNode({
name,
price,
active
}) {
const wrapItemNode = document.createElement("div");
wrapItemNode.classList.add("wrap__item");
if (active === true) {
wrapItemNode.classList.add('active');
}
wrapItemNode.innerHTML = `
<div class="wrap__item-name">${name}</div>
<div class="wrap__item-price">${price}</div>
`;
return wrapItemNode;
}
insertWrapItemIntoWrap(wrapItemNode, wrapNode) {
wrapNode.append(wrapItemNode);
this.wrapItemCollection.push(wrapItemNode);
}
addEventListenerForWrapItem(wrapItemNode) {
wrapItemNode.addEventListener('click', (e) => {
this.wrapItemCollection.forEach((item) => item.classList.remove("active"));
wrapItemNode.classList.add("active");
});
}
}
new Wrap({
initialWrapItems: [{
name: "Пункт 1",
price: 11,
active: false
},
{
name: "Пункт 2",
price: 22,
active: false
},
{
name: "Пункт 3",
price: 33,
active: true
},
],
selectorWrap: '.wrap',
selectorForm: '#form',
selectorInputNumber: '.input-number',
selectorInputText: '.input-text',
selectorWrapItem: '.wrap__item'
});
* {
margin: 0;
padding: 0;
}
.container {
max-width: 900px;
margin: 0 auto;
padding: 0 15px;
}
.add {
border: 2px solid #000;
margin-top: 20px;
padding: 20px;
}
.wrap {
margin-top: 20px;
}
.wrap__item {
max-width: 100px;
position: relative;
cursor: pointer;
}
.wrap__item:not(:last-child) {
margin-bottom: 20px;
}
.wrap__item.active::before {
content: "";
width: 10px;
height: 10px;
border-radius: 100%;
background-color: #000;
position: absolute;
top: 50%;
right: 0;
}
.wrap__item-name {
font-size: 1.5em;
}
<div class="container">
<div class="add">
<h1>Добавляем что-то</h1>
<form id="form" class="form">
<input class="input input-text" type="text" placeholder="Названия" required>
<input class="input input-number" type="number" placeholder="Цена" required>
<button type="submit" class="btn">Добавить</button>
</form>
</div>
<div class="wrap">
</div>
</div>