Как правильно реализовать уменьшение количества товара?
Работяги, добрый день! Пишу проект на html/sass/js, и столкнулся с такой проблемой как: есть две кнопки(уменьшить/увеличить количество товара), при нажатии на кнопку уменьшить визуально товар прибавляется, а переменная уменьшается(скрины будут ниже(извиняюсь за корявый скрин)). Хотел бы узнать почему так!
let btn = document.querySelectorAll('.item-incr-button')
let btnDec = document.querySelectorAll('.item-decr-button')
let i = 1;
btnDec.forEach((btn) => {
btn.addEventListener('click', () => {
let btnId = btn.getAttribute('data-decr-id')
let currentId = document.querySelector(btnId)
currentId.innerText = i
i--
if(i === 0) {
currentId.classList.remove('show')
}
console.log(i)
})
})
btn.forEach((button) => {
button.addEventListener('click', () => {
button.classList.add('add')
button.innerText = ''
let btnId = button.getAttribute('data-incr-id')
let currentId = document.querySelector(btnId)
currentId.innerText = i
i++
currentId.classList.add('show')
console.log('incr')
})
})
<div class="page-item">
<div class="item-counter" id="btn_1"></div>
<div class="item-photo">
<picture class="item-lottie">
<img src="src/image/Burger_148.png" alt="">
<source type="application/x-tgsticker" srcset="src/image/Burger_148.png">
<canvas width="74" height="74"></canvas>
</picture>
</div>
<div class="item-label">
<span class="item-title">
Burger
</span>
<span class="item-price">
$4.99
</span>
</div>
<div class="item-buttons">
<button class="item-decr-button" data-decr-id="#btn_1">
</button>
<button class="item-incr-button" data-incr-id="#btn_1">
<span class="button-item-label">Add</span>
</button>
</div>
</div>
<div class="page-item">
<div class="item-counter" id="btn_2"></div>
<div class="item-photo">
<img src="src/image/Burger_148.png" alt="">
</div>
<div class="item-label">
<span class="item-title">
Burger
</span>
<span class="item-price">
$4.99
</span>
</div>
<div class="item-buttons">
<button class="item-decr-button" data-btn-id="#btn_2">
</button>
<button class="item-incr-button" data-btn-id="#btn_2">
<span class="button-item-label">Add</span>
</button>
</div>
</div>
Ответы (1 шт):
- Изначально у вас проблема была просто в том, что вы выводили значение счетчика до того, как его изменять.
currentId.innerText = i
i--
// должно быть наоборот
i--
currentId.innerText = i
Получалось, что при клике на - у вас визуально увеличивалось, а по факту уменьшалось. Т.к. в вашей реализации вы сначала выводите i (то что получиолсь от предыдущего действия), а только потом его уменьшаете/увеличиваете.
В вашей реализации вы храните значение счетчика в одной общей для всех счетчиков переменной
i. Как писали в комментариях, это приведет к тому, что при попытке изменить значение счетчика на одном товаре, оно по факту будет меняться для всех.Не обязательно для каждой кнопки делать уникальный data-атрибут для id, можно обойтись просто
data-idи для кнопки-и для+.Вообще, я так понимаю, вы пытаетесь сделать нечно вроде корзины заказа. Если так, то вам надо хранить состояние корзины в отдельном объекте и работать с ним. Что-то типа такого:
{
"<id_tovara>": {"qty": "<kol_vo_tovara_v_zakaze", "size": "<razmer_porcii>"}
"tov_1": {"qty": 1, "size": "large"},
"tov_2": {"qty": 1, "size": "large"},
}
И потом еще сохранять этот объект корзины где-то либо в куках, либо в localStorage, чтобы не терять корзину при обновлении страниыц или переходе на другую.
Накидал примерчик, как то что вам нужно можно написать. Не идеально, кучу всего еще можно там улучшить. Так же в примере нет объекта корзины и сохранения состояния в куказ/хранилище. Это уже выходит за рамки вопроса :)
let btn = document.querySelectorAll('.item-incr-button')
let btnDec = document.querySelectorAll('.item-decr-button')
/// Отдельный метод для прибавления/убавления значения в счетчике
function addSubCounter(id, value) {
let counter = document.querySelector(id)
// На всякий случай, храним значение счетчика в data-атрибуте конкретного счетчика.
// Его можно было бы брать и из innerText, но лучше не надо
let qty = counter.getAttribute('qty') * 1 || 0
// Сначала изменяем значение в счётчике,
qty += value
// потом делаем валидацию значения
if (qty <= 0) {
counter.classList.remove('show')
qty = 0
} else {
counter.classList.add('show')
}
// и уже после этого делаем вывод и сохранение нового значения в data-атрибуте
counter.innerText = qty
counter.setAttribute('qty', qty)
}
btnDec.forEach((btn) => {
btn.addEventListener('click', () => {
let btnId = btn.getAttribute('data-id')
addSubCounter(btnId, -1)
console.log('decr')
})
})
btn.forEach((button) => {
button.addEventListener('click', () => {
button.classList.add('add')
button.innerText = ''
let btnId = button.getAttribute('data-id')
addSubCounter(btnId, 1)
console.log('incr')
})
})
.item-counter {
display: none;
}
.item-counter.show {
display: block;
}
<div class="page-item">
<div class="item-counter" id="btn_1"></div>
<div class="item-photo">
<picture class="item-lottie">
<img src="src/image/Burger_148.png" alt="">
<source type="application/x-tgsticker" srcset="src/image/Burger_148.png">
<canvas width="74" height="74"></canvas>
</picture>
</div>
<div class="item-label">
<span class="item-title">
Burger
</span>
<span class="item-price">
$4.99
</span>
</div>
<div class="item-buttons">
<button class="item-decr-button" data-id="#btn_1">
</button>
<button class="item-incr-button" data-id="#btn_1">
<span class="button-item-label">Add</span>
</button>
</div>
</div>
<div class="page-item">
<div class="item-counter" id="btn_2"></div>
<div class="item-photo">
<img src="src/image/Burger_148.png" alt="">
</div>
<div class="item-label">
<span class="item-title">
Burger
</span>
<span class="item-price">
$4.99
</span>
</div>
<div class="item-buttons">
<button class="item-decr-button" data-id="#btn_2">
</button>
<button class="item-incr-button" data-id="#btn_2">
<span class="button-item-label">Add</span>
</button>
</div>
</div>
