我正在开发一个小型 JavaScript 应用程序,用户可以单击页面上的按钮并将其传递到他们的购物篮。我这样做的问题是我不确定在同一个函数中处理多个按钮。我不想为每个按钮写出不同的功能。
我正在尝试 OOP 并且到目前为止:
var shop = {};
shop.items = [];
shop.Item = function(item, description, price) {
this.item = item;
this.description = description;
this.price = price;
};
shop.print = function() {
var itemCon = document.getElementById('items'),
html = "";
for(var i = 0; i < this.items.length; i++) {
html += '<div id="item">';
for(prop in this.items[i]) {
html += '<p><span class="title">' + prop + '</span>: ' + this.items[i][prop] + '</p>';
};
html += '<button id="' + this.items[i].item + '">Add to Basket</button>'
html += '</div>';
};
itemCon.innerHTML += html;
};
shop.items[shop.items.length] = new shop.Item("Coat", "Warm", "20");
shop.items[shop.items.length] = new shop.Item("Coat", "Warm", "20");
shop.items[shop.items.length] = new shop.Item("Coat", "Warm", "20");
shop.items[shop.items.length] = new shop.Item("Coat", "Warm", "20");
var basket = {};
basket.items = [];
basket.Item = function(item, description, price) {
this.item = item;
this.description = description;
this.price = price;
};
basket.add = function(data) {
this.items[items.length] = new Item(data.item, data.description, data.price);
};
basket.costCalculate = function() {
var cost = 0,
html = "Total: " + cost;
for(var i = 0; i < this.items.length; i++) {
cost += items[i].price;
};
return html;
};
basket.print = function() {
var output;
for(var i = 0; i < this.items.length; i++) {
for(prop in this.items[i]) {
console.log(prop + ": " + this.items[i][prop]);
};
};
};
function init() {
shop.print()
};
window.onload = init;
我如何确定点击了哪个项目以运行 basket.add(data)。我还将如何将数据传递给每个项目的该函数。
另外,如何实现闭包?我知道是内部函数可以访问外部函数的变量,到目前为止我正在使用闭包吗?
最佳答案
好的,你已经有了一个很好的开始,但这里有一些建议:
每个
Item
都只有一个实例可能是个好主意.我的意思是看起来你创建了一堆Item
用于填充您商店的库存,例如:var coat = new Item("Coat", "Warm", 20); shop.items.push(coat);
现在,当您单击您的 UI 元素时,理想情况下您想要
coat
的同一实例也进入你的篮子,所以:// User clicks on UI element, which triggers the following to execute: basket.add( someItemIdentifier );
现在,如果您决定将所有价格提高 10 美元,您只需执行以下操作:
shop.increasePricesBy = function(amount) { for(var i = 0; i < shop.items.length; i++) { shop.items[i].price += amount; } // execute some function to update existing baskets' totals };
我希望这能解释为什么多个集合引用的每个项目都应该有一个实例。
这引出了一个问题,即如何将客户的互动与添加正确的商品联系起来。一种解决方案是使用任意 ID 来跟踪项目。例如:
// Create new item with some randomly generated ID var coat = new Item({ id: "93523452-34523452", name: "Coat", description: "Warm", price: 20 }); shop.items = {}; // Use a hash so it's easier to find items shop.items[coat.id] = coat;
你的 UI 元素可以是像这样的一些 div:
<div class="add-product-button" data-id="93523452-34523452">
添加您的点击处理程序:
// Pure JS solution - untested var clickTargets = document.getElementsByClassName("add-product-button"); for(var i = 0; i < clickTargets.length; i++) { var clickTarget = clickTargets[i]; clickTarget.onClick = function() { var itemID = clickTarget.getAttribute("data-id"); var item = shop.items[itemID]; basket.add(item); }; } // Equivalent jQuery code $(".add-product-button").click(function() { var id = $(this).attr('data-id'); var item = shop.items[id]; basket.add(item); });
当您的篮子实现
add
像这样的东西:basket.add = function(items) { this.items.push(item); };
还有你的
costCalculate
方法变得容易得多:basket.costCalculate = function() { var cost = 0; for(var i = 0; i < this.items.length; i++) { cost += this.item[i].price; } return cost; };
而不是这样做:
shop.items[shop.items.length] = new shop.Item("Coat", "Warm", "20");
您可以改为:
shop.items.push(new shop.Item("Coat", "Warm", "20");
使用数字而不是字符串来表示价格可能是个好主意。
在你的
shop.print
循环,你可能不想硬编码<div id="item">
因为这会导致多个 div 具有相同的 id。最后,我不会在这里尝试回答您的关闭问题,因为我认为这个问题的回答比我现在能做的更好,所以我将把您链接到一些帮助我理解它的重要资源:
- > Best stackoverflow thread on how JS Closures work
- > MDN's doc on closures
- > Javascript: The Good Parts by Douglas Crockford .这是一本小书,讨论了一些很棒的概念 - 特别是使用原型(prototype),我想你会发现它对你完成这个项目很有用。
如果您有任何问题,请告诉我,我非常乐意与您讨论。
关于javascript - 纯JS |篮子 |关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27101874/