我是JS的初学者,在购物车上工作。我有几个产品在页面中呈现ES6模板字符串。到目前为止一切正常,你可以添加项目到篮子和篮子,并正确更新。我遇到问题的唯一部分是增加/减少按钮:它们只工作一次,如果再次点击,控制台中打印的数量保持不变。
我确实找到了与增量/减量函数相关的其他SO帖子,但按钮只保持一次工作,所以我认为问题与我忽略的代码中的其他内容有关。
请参阅以下代码:
这是将要呈现的购物车
// select ul
const shoppingCart = document.querySelector('.cart-items');
// create a li item inside ul
let billContainer = document.createElement('li');
// attach an event listener to every li
billContainer.classList.add('list');
// create the markup for every item added to the cart
for(let j = 0; j < basket.length; j++){
const billMarkup = `
<p class="prodName">${basket[j].name}</p>
<div class="button-wrapper">
<button type="button" name="increase" class="increase">+</button>
<span class="quantity">${basket[j].quantity}</span>
<button type="button" name="decrease" class="decrease">-</button>
</div>
<p class="totPrice">£${basket[j].price}</p>
`;
// add the markup to the DOM
billContainer.innerHTML = billMarkup;
shoppingCart.appendChild(billContainer);
}
这是增加/减少功能(按钮的事件监听器附加到其父'li'):
// attach an event listener to every li
const li = document.querySelectorAll('.list');
li.forEach( liItem => liItem.addEventListener('click', updateBill));
// add or remove items on click
function updateBill(e){
if(e.target.nodeName === 'BUTTON'){
// current value in the basket
let value = parseInt(this.querySelector('.quantity').textContent);
// if the user clicks on 'increase' button
if(e.target.name === 'increase'){
value++;
console.log(value);
// if the user clicks on 'decrease' button
} else if(e.target.name === 'decrease'){
value < 1 ? value = 1 : '';
value--;
console.log(value);
}
}
}
谢谢!
答案 0 :(得分:1)
加/减按钮只需减少一次,然后再不再减少。
一旦值发生了变化,它只是一个浮动在控制台中的变量中的数字,因为这是与该值有关的最后一个语句。因此,只有初始更改成功,但是当第二次单击按钮时,该功能将返回span.quantity
并获取从最后一次点击中未更新过的值。
解决手头问题的最简单方法是更新span.quantity
:
if (e.target.name === 'increase') {
value++;
console.log(value);
} else if (e.target.name === 'decrease') {
value--;
value = value < 1 ? 1 : value;
console.log(value);
} else {
return false;
}
this.querySelector('.quantity').textContent = value;
因为您没有提供功能性或可复制的演示,所以我没有费心去测试它,也没有尝试检查您的代码。重写源并解决问题并且可能在将来防止出现问题的努力较少。
<小时/>
Demo使用不同的API来引用表单控件和替代方法和属性,这些方法和属性是更常用的更好的版本。使用事件委派。数组方法可能有点矫枉过正,但我喜欢使用它们。以下是对Demo的行项目引用,遗憾的是,Stack Snippets没有行号。 Plunker - index.html and README.md可以与行号一起阅读。
52声明<form>
,
53引用所有表单控件,
92-95为每个表单控件创建非常简短的引用,
96-99创建对其值的引用并将其转换为数字
102-103,109-110简单和简短的表达,
122总值
75-83通过使用语义元素改进了列表项的布局。每个元素都分配了一个唯一的#id,
92-94灵活引用来自89和90结果的#ids。
数组方法
90-91通过规划特定的命名策略:abc-0
,split('-').pop()
返回ID的数字末尾,split('-').shift()
返回短划线前的字母,
52参考<form>
,
54注册<form>
以点击活动。这是唯一需要的EventListener,它适用于所有子/后代,
88-91,100具有Event.target
属性的事件的参考原点,不仅可以确定点击的元素,还可以确定其他元素,如兄弟姐妹,父母/祖先和子女/后代。
<强>杂强>
56-71看起来basket
是一个对象数组?没有在OP中看到它所以我不得不猜测。删除了basket[j].quantity
属性,因为更有意义的是每个项目的最初数量为1.
84 insertAdjacentHTML()
innerHTML
类固醇。
<!DOCTYPE html>
<html>
<head>
<style>
html,
body {
font: 400 16px/1.1 Consolas;
}
legend {
font-size: 1.3rem;
}
output,
input {
display: inline-block;
text-align: center;
}
[id^=qty] {
width: 1.5ch;
}
[id^=prc] {
min-width: 9ch;
}
[id^=prc]::before {
content: "= £";
}
[id^=bas]::before {
content: " x £";
}
#cart+label {
display: inline-block;
margin: 10px 0 0 40%;
}
#total::before {
content: " £";
}
</style>
</head>
<body>
<form id='cart'></form>
<label>Total:
<output id='total' form='cart'>0.00</output>
</label>
<script>
var cart = document.forms.cart;
var x = cart.elements;
cart.addEventListener('click', updateBill, false);
var basket = [{
name: "thing0",
price: 1.99
}, {
name: "thing1",
price: 12.99
}, {
name: "thing2",
price: 21.59
}, {
name: "thing3",
price: 0.09
}, {
name: "thing4",
price: 5.99
}];
for (let j = 0; j < basket.length; j++) {
var details = `
<fieldset id="item-${j}">
<legend>${basket[j].name}</legend>
<button id="inc-${j}" type="button">+</button>
<output id="qty-${j}">1</output>
<button id="dec-${j}" type="button">-</button>
<output id="bas-${j}">${basket[j].price}</output>
<output id="prc-${j}" class="prc">${basket[j].price}</output>
</fieldset>
`;
cart.insertAdjacentHTML('beforeend', details);
}
function updateBill(e) {
if (e.target.type === 'button') {
var ID = e.target.parentElement.id;
var idx = ID.split('-').pop();
var dir = e.target.id.split('-').shift();
var qty = x.namedItem(`qty-${idx}`);
var bas = x.namedItem(`bas-${idx}`);
var prc = x.namedItem(`prc-${idx}`);
var sum = x.total;
var quantity = parseInt(qty.value, 10);
var base = parseFloat(bas.value).toFixed(2);
var price = parseFloat(prc.value).toFixed(2);
var total = parseFloat(sum.value).toFixed(2);
if (dir === "inc") {
quantity++;
qty.value = quantity;
prc.value = quantity * base;
} else {
quantity--;
if (quantity <= 0) {
quantity = 1;
}
qty.value = quantity;
prc.value = quantity * base;
}
}
var prices = Array.from(document.querySelectorAll('.prc'));
var numbers = prices.map(function(dig, idx) {
return parseFloat(dig.value);
});
var grandTotal = numbers.reduce(function(acc, cur) {
return acc + cur;
}, 0);
x.total.value = grandTotal.toFixed(2);
}
</script>
</body>
</html>
&#13;