проблема со счетчиком товара в корзине
Не правильно работает счетчик товара, чем больше товаров тем больше счетчик +-.
Структура кода.
При нажатии кнопки добавить в корзину:
$('.btn-add-cart').click(function(e){
createCartElement(); });
Идет вызов функции в которой, при каждом нажатии, создается карточка с товаром:
out += '<button class="btn-counter minus"><p class="btn-text">-</p></button>';
out += '<input class="counter" value="1">';
out += '<button class="btn-counter plus"><p class="btn-text">+</p></button>';
cartItem.innerHTML = out;
cartItems.append(cartItem);
Внутри этой же функции обрабатывается нажатие на кнопки + и - с выводом счетчика:
$('.btn-counter.plus').click(function(e) {
let input = parseInt(e.target.parentElement.parentElement.children[1].value);
input = input + 1;
e.target.parentElement.parentElement.children[1].value = input;
});
$('.btn-counter.minus').click(function(e) {
let input = parseInt(e.target.parentElement.parentElement.children[1].value);
input = input - 1;
e.target.parentElement.parentElement.children[1].value = input;
if (input == 0) {
input = 1;
}
});
И так, суть проблемы заключается в том, что при первом нажатии на кнопку (добавить в корзину)- добавляется один товар и все работает хорошо, счетчик добавляет +1 и -1, создали еще одну, старая карточка +2 -2, а новая +1 -1 итд (+3 -3), скорее всего при создании нового элемента оно передает значение старому, прошу помочь с данной проблемой, пробовал уже разные варианты, ничего толкового не нашел.
Ответы (2 шт):
это просто пример, но он показывает что надо
const wrapItems = document.querySelector('#list');
const createButton = (isAdd, elementInput) => {
let operation;
let cssClass;
const btn = document.createElement('button');
if (isAdd === true) {
operation = '+';
cssClass = 'plus'
btn.onclick = () => elementInput.value = parseInt(elementInput.value, 10) + 1;
} else {
operation = '-';
cssClass = 'minus';
btn.onclick = () => elementInput.value = parseInt(elementInput.value, 10) - 1;
}
btn.classList.add('btn-counter', cssClass);
btn.innerHTML = `<p class="btn-text">${operation}</p>`;
return btn;
}
document.querySelector('#add-item').addEventListener('click', () => {
const itemDiv = document.createElement('div');
const input = document.createElement('input');
input.setAttribute('type', 'text');
input.value = 1;
const btnPlus = createButton(true, input);
const btnMinus = createButton(false, input);
itemDiv.append(btnMinus, input, btnPlus);
wrapItems.appendChild(itemDiv);
});
<button id="add-item">add</button>
<div id="list"></div>
а еще, если это допустимо, можно использовать
<input type="number" step="1" min="0">
На один и тот же DOM-элемент можно вешать сколько угодно слушателей событий.
Проблема твоего решения в том, что ты вешаешь обработчики события при каждом добавлении нового счетчика, используя при этом общий селектор.
То есть, создал кнопку -> повесил события на все кнопки с селектором .btn-counter.plus. В твоем случае ход действий получился такой
1. Создать счетчик 1
2. Добавить в DOM.
3. Повесить событие на счетчик 1. (1 х1)
4. Создать счетчик 2
5. Добавить в DOM.
6. Повесить событие на счетчик 1 и 2 (1 х2, 2 х1)
7. Создать счетчик 3
8. Добавить в DOM.
9. Повесить событие на счетчик 1, 2 и 3 (1 х3, 2 х2, 3 х1)
... и тд.
Есть еще общая проблема с производительностью кода. Добавление через innerHTML заставляет лишний раз напрягаться браузерный парсер, чтобы разделить весь текст на токены и сгенерировать исполняемый код.
Лучше упростить задачу браузеру:
const createButton = (className, text, clickListener) => {
const btn = document.createElement('button');
btn.className = className;
const label = document.createElement('p');
label.className = 'btn-text';
label.appendChild(document.createTextNode(text));
btn.addEventListener('click', clickListener);
btn.appendChild(label);
return btn;
};
const createInput = () => {
const input = document.createElement('input');
input.className = 'counter';
input.value = 1;
return input;
};
const createCartElement = () =>
cartItems.append(
createButton('btn-counter minus', '-', removeFromCart); // TODO: implement removeFromCart
createInput(),
createButton('btn-counter plus', '+', addToCart); // TODO: implement addToCart
);
}