所以基本上我正在制作一個在線餐廳網站,您可以在其中訂購食物。我將為列出的每種食品制作卡片。現在,我正在制作添加和減去客戶想要購買的每件商品數量的按鈕。
var counter = document.querySelector(".count");
var currentNumber = 0;
var classicBurger = 5.18;
var bargeBurger = 6.13;
function addOne(price) {
currentNumber = 1;
counter.innerHTML = currentNumber;
document.querySelector(".total-price").innerHTML =
"$" (price * currentNumber).toFixed(2);
}
function subtractOne(price) {
if (currentNumber > 0) {
currentNumber = -1;
counter.innerHTML = currentNumber;
document.querySelector(".total-price").innerHTML =
"$" (price * currentNumber).toFixed(2);
} else {
counter.innerHTML = 0;
}
}
<html>
<div class="food-item">
<h3 class="item-title">Classic Burger</h3>
<p class="item-description">
Classic beef patty with lettuce, tomato, and cheese.
</p>
<div class="add-subtract-items">
<button class="subtract-item" onclick="subtractOne(classicBurger)">
-
</button>
<span class="count">0</span>
<button class="add-item" onclick="addOne(classicBurger)"> </button>
</div>
<p class="total-price">$0.00</p>
</div>
<div class="food-item">
<h3 class="item-title">Barge Burger</h3>
<p class="item-description">
Classic beef patty with lettuce, tomato, and cheese.
</p>
<div class="add-subtract-items">
<button class="subtract-item" onclick="subtractOne(bargeBurger)">
-
</button>
<span class="count">0</span>
<button class="add-item" onclick="addOne(bargeBurger)"> </button>
</div>
<p class="total-price">$0.00</p>
</div>
<html/>
如何獲得第二個按鈕以影響正確的 HTML 而不是第一個專案的總數?
uj5u.com熱心網友回復:
您的代碼的問題在于您宣告變數的位置,以及您選擇元素的方式:
// here we get the first element in the document:
var counter = document.querySelector(".count");
// we set the currentNumber (the 'count') variable to 0:
var currentNumber = 0;
/* ... */
function addOne(price) {
// regardless of which button, for which menu-item,
// is pressed we increase the count (but this variable
// is applied as the counter for *all* menu-items):
currentNumber = 1;
// here we're using the first '.count' element in the
// document (regardless of which menu-item we're
// trying to order, or remove from the order):
counter.innerHTML = currentNumber;
// and again, we're using the first element within the
// document (regardless of which menu-item the buttons
// relate to):
document.querySelector(".total-price").innerHTML =
"$" (price * currentNumber).toFixed(2);
}
// the same is true, below, for the subtraction function
// which I've removed for brevity
相反,我們需要查看哪個<button>被按下,并從那里找到正確的選單項來增加或減少;因此,在以下代碼中,我利用EventTarget.addEventListener()將對觸發事件的參考傳遞給系結為事件偵聽器的函式:
// declaring named functions using Arrow functions (since we're not using the
// 'this' variable).
// a named function to format the cost to two decimal places:
const formatCost = (cost) => {
return (Math.ceil(cost * 100) / 100).toFixed(2);
},
// the following functions take advantage of EventTarget.addEventListener()
// passing the event-object to the function that's bound as the event-listener:
addOne = (evt) => {
// from the event-object we first retrieve the 'evt.currentTarget', this
// is the element to which the event-listener was bound (in this case the
// <button > elements), from there we use Element.closest()
// to find the ancestor <div > element (effectively to find
// the first ancestor that wraps the <button> elements as well as the other
// elements we wish to use):
let cardParent = evt.currentTarget.closest('div.food-item'),
// from the cardParent we then use Element.querySelector() to select
// the first element within that Element (the cardParent) that matches
// the supplied CSS selector:
costElement = cardParent.querySelector('span.cost'),
countElement = cardParent.querySelector('span.count'),
// from those elements we determine the cost, using parseFloat()
// to convert the text-content of the element into a number we
// can work with:
cost = parseFloat(costElement.textContent),
// we update the current count by adding 1 to the number
// retrieved with parseInt():
count = parseInt(countElement.textContent) 1;
// we then update the countElement to reflect the new - increased - count:
countElement.textContent = count;
// and we then find the '.total-price' element, and update its text-content
// to reflect the formatted cost:
cardParent.querySelector('.total-price').textContent = formatCost(cost * count);
},
subtractOne = (evt) => {
// here we do almost exactly as we did above:
let cardParent = evt.currentTarget.closest('div.food-item'),
costElement = cardParent.querySelector('span.cost'),
countElement = cardParent.querySelector('span.count'),
cost = parseFloat(costElement.textContent),
// obviously we don't (yet) adjust the count:
count = parseInt(countElement.textContent);
// because we first need to check that the count is greater than zero:
if (count > 0) {
// if so, we then subtract one from the count:
count = count - 1;
// we then update the countElement to reflec the new count:
countElement.textContent = count;
}
// and finally we update the '.total-price' element to reflect the new cost:
cardParent.querySelector('.total-price').textContent = formatCost(cost * count);
};
// here we select all elements in the document that match the supplied CSS selector, and
// use NodeList.forEach() to iterate over those elements, and:
document.querySelectorAll('button.subtract-item').forEach(
// we then bind the subtractOne() function (note the lack of parentheses)
// as the 'click' handler for the current element of the NodeList:
(subtraction) => subtraction.addEventListener('click', subtractOne)
);
// as above, but obviously we're binding the addOne() function
// to the 'button.add-item' elements:
document.querySelectorAll('button.add-item').forEach(
(addition) => addition.addEventListener('click', addOne)
);
*,
::before,
::after {
box-sizing: border-box;
font: normal 400 1rem / 1.5 sans-serif;
margin: 0;
padding: 0;
}
body {
display: flex;
flex-wrap: wrap;
gap: 1em;
padding: 1em;
}
.food-item {
border: 1px solid #000;
border-radius: 1em;
padding: 0.5em;
}
h3 {
font-weight: 600;
}
.add-subtract-items {
align-content: center;
display: flex;
gap: 0.5em;
justify-content: center;
width: minmax(6em, 40%);
}
button,
span.count {
text-align: center;
}
button {
cursor: pointer;
width: 2em;
}
:is(.cost, .total-price)::before {
content: "$";
}
<div class="food-item">
<h3 class="item-title">Classic Burger</h3>
<span class="cost">5.18</span>
<p class="item-description">
Classic beef patty with lettuce, tomato, and cheese.
</p>
<div class="add-subtract-items">
<button class="subtract-item">
-
</button>
<span class="count">0</span>
<button class="add-item"> </button>
</div>
<p class="total-price">0.00</p>
</div>
<div class="food-item">
<h3 class="item-title">Barge Burger</h3>
<span class="cost">6.13</span>
<p class="item-description">
Classic beef patty with lettuce, tomato, and cheese.
</p>
<div class="add-subtract-items">
<button class="subtract-item">
-
</button>
<span class="count">0</span>
<button class="add-item"> </button>
</div>
<p class="total-price">0.00</p>
</div>
<div class="food-item">
<h3 class="item-title">Milkshake</h3>
<span class="cost">4.35</span>
<p class="item-description">
Tastes like a five-dollar shake, for a little bit less.
</p>
<div class="add-subtract-items">
<button class="subtract-item">
-
</button>
<span class="count">0</span>
<button class="add-item"> </button>
</div>
<p class="total-price">0.00</p>
</div>
JS 小提琴演示。
參考:
- 箭頭函式。
EventTarget.addEventListener().Math.ceil().NodeList.forEach().parseFloat().parseInt().
uj5u.com熱心網友回復:
主要問題是currentNumber兩個計數器之間共享,因此無法區分一個與另一個。
此外,在 HTML 中保持狀態(每個漢堡的當前價格)和使用onclick使得管理范圍變得困難。
我建議從 HTML 中洗掉所有狀態,然后在.food-item元素上撰寫一個回圈以將點擊處理程式添加到它們的按鈕并能夠操縱它們的每個輸出。您可以使用資料結構burgers來跟蹤每個漢堡的價格,而不是單獨的變數,這些變數不適合回圈。
這是一種方法:
const burgers = [
{name: "Classic Burger", price: 5.18},
{name: "Barge Burger", price: 6.13},
];
const foodItemEls = [...document.querySelectorAll(".food-item")];
foodItemEls.forEach((e, i) => {
let quantity = 0;
e.querySelector(".add-item").addEventListener("click", () => {
quantity;
showTotal();
});
e.querySelector(".subtract-item").addEventListener("click", () => {
quantity = Math.max(quantity - 1, 0);
showTotal();
});
const showTotal = () => {
e.querySelector(".total-price").textContent =
"$" (burgers[i].price * quantity).toFixed(2);
};
});
<div class="food-item">
<h3 class="item-title">Classic Burger</h3>
<p class="item-description">
Classic beef patty with lettuce, tomato, and cheese.
</p>
<div class="add-subtract-items">
<button class="subtract-item">-</button>
<span class="count">0</span>
<button class="add-item"> </button>
</div>
<p class="total-price">$0.00</p>
</div>
<div class="food-item">
<h3 class="item-title">Barge Burger</h3>
<p class="item-description">
Classic beef patty with lettuce, tomato, and cheese.
</p>
<div class="add-subtract-items">
<button class="subtract-item">-</button>
<span class="count">0</span>
<button class="add-item"> </button>
</div>
<p class="total-price">$0.00</p>
</div>
If you have more burgers, you might want to keep them all in an array like burgers shown above, and generate and inject the HTML using a loop over that data structure. To do this, you'd add the description to the array as well. That said, I'm not sure if it's the right fit for your app without more context.
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/441716.html
標籤:javascript html dom
