我正在为一家虚构的在线商店开发购物车功能。此功能的核心是一个
Cart
类,用于管理信息并执行计算。该类不与 HTML 文档或 DOM 交互,它只是执行计算。
Cart
类具有管理产品的方法。每个产品都有一个 SKU、标题、价格属性,我也尝试添加一个数量属性,但我认为它不起作用。我有两个按钮,addButton
和 subtractButton
,用于每种产品增加或减少数量。
我想实现以下目标:
addButton
时,产品数量应增加 1,并且该 SKU 的总价格应在 total-SKU
范围内更新。subtractButton
时,产品数量应减少 1(如果大于 0),并且该 SKU 的总价应在 total-SKU
范围内更新。total
div 中。这是jsFiddle中的代码:https://jsfiddle.net/mlpz2/edfjLhb2
这是代码:
class Cart {
constructor(products, currency) {
this.products = [];
this.currency = "";
}
initializeQuantity = () => {
for (let product of this.products) {
product.quantity = 0; // Initialize quantity to 0 for each product
}
console.log(this.products.quantity);
};
updateUnits = (sku, units) => {
// Update the number of units to be purchased for a product
let product = this.products.find((p) => p.sku === sku);
if (product) {
product.quantity = units;
console.log(this.products.quantity);
} else {
this.products.push({ sku: sku, quantity: units });
}
};
getProductInformation = (sku) => {
// Returns the data of a product along with the selected units
// For example:
// {
// "sku": "0K3QOSOV4V",
// "quantity": 3
// }
return this.products.find((p) => p.sku === sku);
};
getAllProducts = () => {
return this.products;
};
getCart = () => {
// Returns information about the products added to the cart
// Along with the calculated total of all products
// For example:
// {
// "total": "5820",
// "currency: "€",
// "products" : [
// {
// "sku": "0K3QOSOV4V"
// ..
// }
// ]}
let total = this.products.reduce(
(sum, p) => sum + p.quantity * p.price,
0
);
return { total: total, currency: this.currency, products: this.products };
};
}
let cart = new Cart();
cart.initializeQuantity();
const getProductsData = async () => {
let response = await fetch(
"https://jsonblob.com/api/jsonBlob/1241305513466912768"
);
let data = await response.json();
console.log(data);
return data; // return the full response
};
const showProducts = (products) => {
console.log(products);
let productsContainer = document.getElementById("productsContainer");
for (let product of products) {
let quantity = product.quantity || 0; // Initialize quantity here
let productElement = document.createElement("div");
productElement.innerHTML = `
<h2>${product.title}</h2>
<p>Ref: ${product.SKU}</p>
<p>Price: ${product.price}€/unit</p>
<button class="substractButton">-</button>
<span id="quantity-${product.SKU}">${quantity}</span>
<button class="addButton">+</button>
<p>Total: <span id="total-${product.SKU}">0</span>€</p>
`;
productElement.className = "product";
productsContainer.appendChild(productElement);
let addButtons = productElement.querySelectorAll(".addButton");
for (let i = 0; i < addButtons.length; i++) {
addButtons[i].addEventListener('click', () => updateQuantity(product.SKU, 1));
}
console.log(addButtons);
let subtractButtons = productElement.querySelectorAll(".substractButton");
for (let i = 0; i < subtractButtons.length; i++) {
subtractButtons[i].addEventListener('click', () => updateQuantity(product.SKU, -1));
console.log(typeof subtractButtons[i], subtractButtons[i]);
}
}
console.log(productsContainer);
};
const updateTotal = (sku) => {
let products = cart.getAllProducts(); // Assuming getCart returns an array of products
let total = 0;
console.log(products); // Check if the products are being fetched correctly
for (let product of products) {
total += product.quantity * product.price;
}
document.getElementById('total').textContent = `TOTAL: ${total}`; // Assuming 'total' is the id of the element displaying the total price
};
const updateQuantity = (sku, change) => {
let product = cart.getProductInformation(sku);
if (product) {
product.quantity += change;
if (product.quantity < 0) {
// Ensure the quantity doesn't go below 0
product.quantity = 0;
}
document.getElementById(`quantity-${sku}`).textContent = product.quantity;
document.getElementById(`total-${sku}`).textContent =
product.quantity * product.price;
updateTotal();
}
};
getProductsData().then((data) => {
if (data && data.products) {
cart.products = data.products;
cart.products = data.products.map((product) => {
return {
...product,
price: parseFloat(product.price),
};
}); // assign the currency to the cart object
showProducts(cart.products);
updateTotal();
} else {
console.error("Failed to fetch products");
}
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="productsContainer">
<div id="total">
<!-- The total will be shown here -->
</div>
</div>
<script src="script.js"></script>
</body>
</html>
#productsContainer {
display: flex;
flex-direction: column;
flex-wrap: wrap;
margin-top: 20px;
position: relative;
}
.product {
width: 200px;
margin: 10px;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
text-align: center;
}
#total {
position: absolute;
font-size: 20px;
font-weight: bold;
bottom: -20px;
left: 10px;
background-color: #ececec;
}
@media (min-width: 768px) {
#productsContainer {
flex-direction: row;
}
}
产品是从 API 获取的。我正在使用 jsonblob.com(https://jsonblob.com/api/jsonBlob/1241305513466912768) 创建一个模拟 API。
{
"currency": "€",
"products": [
{
"SKU": "0K3QOSOV4V",
"title": "iFhone 13 Pro",
"price": "938.99"
},
{
"SKU": "TGD5XORY1L",
"title": "Cargador",
"price": "49.99"
},
{
"SKU": "IOKW9BQ9F3",
"title": "Funda de piel",
"price": "79.99"
}
]
}
我想我不知道如何:
我不确定如何为
addButton
和 subtractButton
创建事件监听器以及如何更新 DOM 中的数量和总价。
我也愿意接受任何改进代码的建议。任何帮助将不胜感激!
感谢您的阅读:)
为所有按钮分别添加事件监听器,并检查带有 id 的事件以更新特定元素。
希望这有帮助。
class Cart {
constructor(products, currency) {
this.products = [];
this.currency = "";
}
initializeQuantity = () => {
for (let product of this.products) {
product.quantity = 0; // Initialize quantity to 0 for each product
}
console.log(this.products.quantity);
};
updateUnits = (sku, units) => {
// Update the number of units to be purchased for a product
let product = this.products.find((p) => p.sku === sku);
if (product) {
product.quantity = units;
console.log(this.products.quantity);
} else {
this.products.push({ sku: sku, quantity: units });
}
};
getProductInformation = (sku) => {
// Returns the data of a product along with the selected units
// For example:
// {
// "sku": "0K3QOSOV4V",
// "quantity": 3
// }
return this.products.find((p) => p.SKU === sku);
};
getAllProducts = () => {
return this.products;
};
getCart = () => {
// Returns information about the products added to the cart
// Along with the calculated total of all products
// For example:
// {
// "total": "5820",
// "currency: "€",
// "products" : [
// {
// "sku": "0K3QOSOV4V"
// ..
// }
// ]}
let total = this.products.reduce(
(sum, p) => sum + p.quantity * p.price,
0
);
return { total: total, currency: this.currency, products: this.products };
};
}
let cart = new Cart();
cart.initializeQuantity();
const getProductsData = async () => {
let response = await fetch(
"https://jsonblob.com/api/jsonBlob/1241305513466912768"
);
let data = await response.json();
console.log(data);
return data; // return the full response
};
const showProducts = (products) => {
console.log(products);
let productsContainer = document.getElementById("productsContainer");
for (let product of products) {
let quantity = product.quantity || 0; // Initialize quantity here
let productElement = document.createElement("div");
productElement.innerHTML = `
<h2>${product.title}</h2>
<p>Ref: ${product.SKU}</p>
<p>Price: ${product.price}€/unit</p>
<button class="substractButton" id=${product.SKU}>-</button>
<span id="quantity-${product.SKU}">${quantity}</span>
<button class="addButton" id=${product.SKU}>+</button>
<p>Total: <span id="total-${product.SKU}">0</span>€</p>
`;
productElement.className = "product";
productsContainer.appendChild(productElement);
let addButtons = productElement.querySelectorAll(".addButton");
addButtons.forEach(button => {
button.addEventListener('click', event => {
updateQuantity(event.target.id, 1);
});
});
console.log(addButtons);
let subtractButtons = productElement.querySelectorAll(".substractButton");
subtractButtons.forEach(button => {
button.addEventListener('click', event => {
updateQuantity(event.target.id, -1);
console.log(event.target);
});
});
}
console.log(productsContainer);
};
const updateTotal = (sku) => {
let products = cart.getAllProducts(); // Assuming getCart returns an array of products
let total = 0;
console.log(products); // Check if the products are being fetched correctly
for (let product of products) {
total += product.quantity * product.price;
}
document.getElementById('total').textContent = `TOTAL: ${total}`; // Assuming 'total' is the id of the element displaying the total price
};
const updateQuantity = (sku, change) => {
let product = cart.getProductInformation(sku);
if (product) {
if(!product.quantity){
product.quantity = 0;
}
product.quantity += change;
if (product.quantity < 0) {
// Ensure the quantity doesn't go below 0
product.quantity = 0;
}
document.getElementById(`quantity-${sku}`).textContent = product.quantity ;
document.getElementById(`total-${sku}`).textContent =
product.quantity * product.price;
updateTotal();
}
};
getProductsData().then((data) => {
if (data && data.products) {
cart.products = data.products;
cart.products = data.products.map((product) => {
return {
...product,
price: parseFloat(product.price),
};
}); // assign the currency to the cart object
showProducts(cart.products);
updateTotal();
} else {
console.error("Failed to fetch products");
}
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="productsContainer">
<div id="total">
<!-- The total will be shown here -->
</div>
</div>
<script src="./product.js"></script>
</body>
</html>