我想做的是制作某种购物车。我们的想法是,页面中有几个产品,下方有“购买”按钮。按购买时,该项目将添加到侧栏中的列表中。如果已经有这样的产品,那么只有数量(数量)增加。
buy prod1 -> 1 x prod1
buy prod1 -> 2 x prod1
等
我无法完成我的阵列。如何添加产品?
这是我的代码:
HTML
<div class="product">
<div class="product_img">
<img src="images/s1.png" alt="s1" width="180" height="110" />
</div>
<div class="product_descr">
<div class="descr_title">
TITLE1
</div>
<div class="descr_text">
Aliquam sed est diam lorem, iaculis malesuada enim quis nequ
</div>
<div class="descr_buy_price">
<div class="price">
2.40 Ls
</div>
<div class="buy">
<a href="#">BUY</a>
</div>
</div>
</div>
<div class="hidden">
<div class="list_item" title="i1">
<div class="item_name"> <span class="quantity"></span> x Produkts1</div>
<div class="item_price">8.99 Ls</div>
<div class="item_x">
<a href="#">
<img src="images/x.png" alt="x" />
</a>
</div>
</div>
</div>
</div>
JS
<script type="text/javascript">
$(document).ready(function() {
$('.buy a').click(function() {
var array_of_items = {};
array_of_items[$(this).parent().parent().parent().parent().find('.list_item').attr('title')] == 1;
if(array_of_items[$(this).parent().parent().parent().parent().find('.list_item').attr('title')] > 0){
array_of_items[$(this).parent().parent().parent().parent().find('.list_item').attr('title')] = +1;
$('.quantity').text(array_of_items[$(this).parent().parent().parent().parent().find('.list_item').attr('title')]);
}
else {
$(this).parent().parent().parent().parent().find('.list_item').clone().appendTo('#all_items');
$('.quantity').text(array_of_items[$(this).parent().parent().parent().parent().find('.list_item').attr('title')]);
}
});
});
</script>
答案 0 :(得分:2)
您的代码存在一些问题:
array_of_items
不是持久的,它只在事件处理程序的一次执行期间存在。您希望通过多次点击使其持久化,因此您必须在处理程序之外声明并初始化它。
if
语句上方的比较是无用的,您不会对返回值执行任何操作。
我认为您希望在+= 1
分支内= +1
代替if
。 += 1
将当前值增加1,而= +1
与= 1
相同,即将值设置为1。
在else
分支中,您还必须将计数器(您的数组条目)设置为1
,否则项目永远不会添加到列表中。
您正在多次访问产品标题。将其值存储在变量中以避免重复调用....parent().parent()...
。这将使您的代码更容易阅读。另请查看.closest()
[docs]。
以下是代码的改进版本:
var items = {}; // needs to be outside
$('.buy a').click(function() {
var $item = $(this).closest('.product').find('.list_item'),
title = $item.attr('title');
if(typeof items[title] === 'undefined') { // item was not added yet
items[title] = 0;
$item.clone().appendTo('#all_items');
}
items[title] += 1; // increase quantity
$('#all_items') // update the correct quantity field
.find('.list_item[title="' + title + '"]')
.find('.quantity').text(items[title]);
});
另外注意:您实际上使用的是对象,而不是数组,但在这种情况下这是正确的。数组将连续的数字索引与值相关联,而对象可用于将任何类型的键(在JS中,它们都是字符串)与值相关联,如hash table [Wikipedia]。
答案 1 :(得分:0)
首先,当您将array_of_items
作为{}
启动时 - 它是一个对象,而不是一个数组。
除了它是对象之外,您还可以使用$.extend()
。 http://api.jquery.com/jQuery.extend/
另外,您应该考虑使用$.parentsUntil()
而不是parent()
混乱。 http://api.jquery.com/parentsUntil/
答案 2 :(得分:0)
解决此类问题的最佳方法是使用模板系统。最简单的模板形式是字符串。
var cartItem = '<div class="cart-item" id="cart-item-$ID">'+
'<p class="cart-item-name">$NAME</p>'+
'<p class="cart-item-price">$PRICE</p>'+
'</div>';
要填充模板,您需要:
cartItem.
replace('$ID', identifier).
replace('$NAME', productName).
replace('$PRICE', productPrice)
您可以使用按钮元素上的data-$KEY
属性将产品详细信息存储为每个按钮中的原始数据。因此,在创建按钮时,您:
<button data-id="002" data-name="My Product" data-price="$12">buy</button>
要读取数据,请使用jQuery的.data()方法:
$('button').on('click', function(e) {
e.preventDefault(); // if it's in a form
$this = $(this);
var id = $this.data('id');
var name = $this.data('name');
var price = $this.data('price');
// now populate template, and append to cart
});
答案 3 :(得分:0)
根本问题是每次单击时都会重置array_of_items。为了保留有意义的信息,需要在click处理程序之外初始化它。每次单击时都会调用单击处理程序中的Everyhting,因此您需要小心地放置不需要在外面运行的任何内容。你在处理程序之外的任何东西仍然可以在它内部访问(它是a bit more complex than that,但对于像你的例子这样的简单情况,它或多或少是真的)
我在下面列出了一些其他改进,代码仍然可以进一步改进。我的建议是通过jQuery docs(至少是Manipulation,Traversing和selector部分)非常好地阅读,因为你可以更好地利用jquery非常有用的一组功能。
$(document).ready(function() {
var array_of_items = {};
$('.buy').delegate("a", "click", function() {
var $this = $(this),
$item = $(this).closest(".product").find('.list_item'),
itemName = $item.attr('title');
if(array_of_items[itemName] > 0){
array_of_items[itemName] = array_of_items[itemName] + 1;
$('.quantity').text(array_of_items[itemName]);
}
else {
array_of_items[itemName] = 1;
$item.clone().appendTo('#all_items');
$('.quantity').text(array_of_items[itemName]);
}
});
});