因此,使用Vanilla Javascript,我设法创建了一个项目下拉列表,一旦单击按钮,该项目就会添加到购物篮中。
我有一个“总成本”部分,该部分应将添加到购物篮中的各项费用加起来。据我所知,我需要设置一个数组并分配一个价格。但是,然后id需要将其与下拉列表(HTML)中的相应项目链接。我认为我需要使用公式来总结这些。最好的方法是什么?还是有人可以给我举个例子?
这是我所拥有的:
var button = document.getElementById("button");
var select = document.getElementById("select");
var basket = document.getElementById("basket");
var totalCost = document.getElementById("total-cost");
function addToBasket() {
var li = document.createElement("li");
li.innerHTML = select.options[select.selectedIndex].text;
basket.appendChild(li);
}
document.getElementById("remove-button").onclick = function() {
var list = document.getElementById("basket");
list.removeChild(list.childNodes[0])
}
button.addEventListener("click", addToBasket);
<div id="select-items">
<form id="myForm">
<p>Item: <select id="select">
<option value="1" id="a">A</option>
<option value="2" id="b">B</option>
<option value="3" id="c">C</option>
<option value="4" id="d">D</option>
</select>
<button id="button" type="button">Add</button></p>
<button id="remove-button" type="button">Remove</button>
</form>
</div>
<div id="basket-total">
<p>Basket</p>
<div id="basket"></div>
</div>
<div id="total-of-basket">
<p>Total Cost</p>
<p id="total-cost"></p>
</div>
我对此很陌生,因此非常感谢您的帮助!谢谢!
答案 0 :(得分:1)
这就是您想要用vanillaJS编写的内容。这不是很复杂,但也不是最简单的。它使用数组和一些您可能不熟悉的数组方法(foreach,reduce)。
基本概念是,您将一个项目封装到具有name
和value
属性的Javascript对象中,然后将其添加到名为myBasket
的数组中。每次添加一项或删除其中一项时,您都将重新计算总成本,并重新打印整个列表。为简单起见,我删除了整个列表,然后从头开始重新打印。
var button = document.getElementById("button");
var select = document.getElementById("select");
var basket = document.getElementById("basket");
var totalCost = document.getElementById("total-cost");
var myBasket = [];
function addToBasket() {
var item = {
value: Number(select.options[select.selectedIndex].value),
name: select.options[select.selectedIndex].text
};
myBasket.push(item)
recalculate();
}
function recalculate() {
printBasket();
printCost();
}
function printCost() {
var cost = myBasket.reduce(function (acc, item) {
return acc + item.value;
}, 0);
totalCost.innerText = cost;
}
function printBasket() {
basket.innerHTML = '';
myBasket.forEach(function(item) {
var li = document.createElement("li");
li.innerHTML = item.name;
basket.appendChild(li);
})
}
document.getElementById("remove-button").onclick = function() {
myBasket.pop();
recalculate();
}
button.addEventListener("click", addToBasket);
<div id="select-items">
<form id="myForm">
<p>Item: <select id="select">
<option value="1" id="a">A</option>
<option value="2" id="b">B</option>
<option value="3" id="c">C</option>
<option value="4" id="d">D</option>
</select>
<button id="button" type="button">Add</button></p>
<button id="remove-button" type="button">Remove</button>
</form>
</div>
<div id="basket-total">
<p>Basket</p>
<div id="basket"></div>
</div>
<div id="total-of-basket">
<p>Total Cost</p>
<p id="total-cost"></p>
</div>
答案 1 :(得分:0)
这是您可以做什么的一个示例。使此解决方案比您的设置更容易使用的原因是,只有一个阵列可以放置和移除选定的产品。添加或删除商品后,将调用refreshBasket
方法,该方法将重新呈现购物篮内容和总价。
有一个带有产品信息的对象。选项上的ID用于获取匹配的产品信息。此信息放置在所选项目的数组中。
我注意到,当购物篮为空时,删除项目的方法会产生错误。您应先检查是否有要删除的项目。
const
products = {
a: { name: 'product A', price: 12.50 },
b: { name: 'product B', price: 7.25 },
c: { name: 'product C', price: 10 },
d: { name: 'product D', price: 17.90 }
},
selectedItems = [];
var button = document.getElementById("button");
var select = document.getElementById("select");
/**
* Gets product information for the provided ID. Passing an ID that doesn't
* have a matching product will return undefined.
*/
function getSelectedProduct(productId) {
return products[productId];
}
/**
* Handles the event which is dispatched when the user adds an item to
* the basket.
*/
function onAddItemToBasket(event) {
// Get the option for the selected item.
const
selectedOption = select.options[select.selectedIndex],
product = getSelectedProduct(selectedOption.id);
// When there is no product with the ID, exit the method.
if (product === undefined) {
return;
}
// Add the selected item to the basket array with selected items.
selectedItems.push(product);
// Refresh the basket.
refreshBasket();
}
/**
* Handles the event which is dispatched when the user removes an item from
* the basket.
*/
function onRemoveItemFromBasket(event) {
// When there are no items there is nothing to do.
if (selectedItems.lenght === 0) {
return;
}
// Remove the item at index 0 from the array.
selectedItems.shift();
refreshBasket();
}
function refreshBasket() {
const
basket = document.getElementById("basket"),
totalCost = document.getElementById("total-cost");
// Create a string with item wrapped in an li element
itemHTML = selectedItems.reduce((html, item) => html + `<li>${item.name} ($ ${item.price})</li>`,''),
// Iterate over all the items and calculate the sum of all the items.
totalPrice = selectedItems.reduce((total, item) => total + item.price, 0);
// Update the inner HTML of the basket element with the items currently selected.
basket.innerHTML = itemHTML;
// Update the price of all the items combined.
totalCost.innerHTML = `$ ${totalPrice}`;
}
const
addTrigger = document.getElementById("button"),
removeTrigger = document.getElementById("remove-button");
addTrigger.addEventListener('click', onAddItemToBasket);
removeTrigger.addEventListener('click', onRemoveItemFromBasket)
<div id="select-items">
<form id="myForm">
<p>Item: <select id="select">
<option value="1" id="a">A</option>
<option value="2" id="b">B</option>
<option value="3" id="c">C</option>
<option value="4" id="d">D</option>
</select>
<button id="button" type="button">Add</button></p>
<button id="remove-button" type="button">Remove</button>
</form>
</div>
<div id="basket-total">
<p>Basket</p>
<div id="basket"></div>
</div>
<div id="total-of-basket">
<p>Total Cost</p>
<p id="total-cost"></p>
</div>
答案 2 :(得分:0)
一种技术是使用data-
属性将当前状态存储在DOM中。这意味着将价格直接放在select
元素上,并在选择价格时对其进行查询:
var button = document.getElementById("button");
var select = document.getElementById("select");
var basket = document.getElementById("basket");
var totalCost = document.getElementById("total-cost");
function addToBasket() {
var li = document.createElement("li");
li.innerHTML = select.options[select.selectedIndex].text;
var price = Number(select.options[select.selectedIndex].dataset.price);
li.dataset.price = price;
basket.appendChild(li);
totalCost.innerHTML = ((Number(totalCost.innerHTML) || 0) + price).toFixed(2);
}
document.getElementById("remove-button").onclick = function() {
var list = document.getElementById("basket");
var price = Number(list.childNodes[0].dataset.price);
list.removeChild(list.childNodes[0]);
totalCost.innerHTML = ((Number(totalCost.innerHTML) || 0) - price).toFixed(2);
}
button.addEventListener("click", addToBasket);
div {float: left; margin-left: 3em;}
<div id="select-items">
<form id="myForm">
<p>Item: <select id="select">
<option value="1" data-price="1.23" id="a">A</option>
<option value="2" data-price="2.35" id="b">B</option>
<option value="3" data-price="7.11" id="c">C</option>
<option value="4" data-price="9.87" id="d">D</option>
</select>
<button id="button" type="button">Add</button></p>
<button id="remove-button" type="button">Remove</button>
</form>
</div>
<div id="basket-total">
<p>Basket</p>
<div id="basket"></div>
</div>
<div id="total-of-basket">
<p>Total Cost</p>
<p id="total-cost"></p>
</div>
这与原来的问题相同,即在空篮子中“删除”会引发错误。那应该很容易解决,但是超出了问题的范围。
我实际上并不认为这是您最好的选择。我认为将数据保留在JS变量中会更好。但是,您需要一种方法,从产生下拉菜单的任何内容中获取它们。如果这是手动的,那不是问题,但是如果这是在服务器端生成的,则可能需要动态生成prices
:
var button = document.getElementById("button");
var select = document.getElementById("select");
var basket = document.getElementById("basket");
var totalCost = document.getElementById("total-cost");
var prices = {a: 1.23, b: 2.35, c: 7.11, d: 9.87} // dynamically generated?
var total = 0;
function addToBasket() {
var li = document.createElement("li");
total += prices[select.options[select.selectedIndex].id];
totalCost.innerHTML = total.toFixed(2);
li.innerHTML = select.options[select.selectedIndex].text;
li.itemId = select.options[select.selectedIndex].id;
basket.appendChild(li);
}
document.getElementById("remove-button").onclick = function() {
var list = document.getElementById("basket");
total -= prices[list.childNodes[0].itemId];
totalCost.innerHTML = total.toFixed(2);
list.removeChild(list.childNodes[0]);
}
button.addEventListener("click", addToBasket);
div {float: left; margin-left: 3em;}
<div id="select-items">
<form id="myForm">
<p>Item: <select id="select">
<option value="1" data-price="1.23" id="a">A</option>
<option value="2" data-price="2.35" id="b">B</option>
<option value="3" data-price="7.11" id="c">C</option>
<option value="4" data-price="9.87" id="d">D</option>
</select>
<button id="button" type="button">Add</button></p>
<button id="remove-button" type="button">Remove</button>
</form>
</div>
<div id="basket-total">
<p>Basket</p>
<div id="basket"></div>
</div>
<div id="total-of-basket">
<p>Total Cost</p>
<p id="total-cost"></p>
</div>
此解决方案仍然在DOM中存储一些状态-选择项目的id
属性和新创建的购物篮项目的itemId
。就是这样。计算使用这些ID在prices
对象中找到正确的价格,并使用javascript total
变量存储当前价格。
同样,我不会在这里解决remove
问题。
老实说,这仍然不是我真正喜欢的代码。我不喜欢全局变量,因此可能会找到一种将其嵌入其他范围的方法。还有其他一些我也可以做的清理工作,但这可能会让您步入正轨。