如何用JavaScript实现购物车商品数量无刷新更新
问题描述
购物车页面中,点击增减商品按钮已能成功修改后端数据,但页面上的商品数量不会自动更新,需要实现无需刷新页面即可同步更新数量的功能。
我的视图代码(Python/Django)
def get_item_quantity(request): user = request.user if user.is_authenticated: try: cart = Cart.objects.get(user=user) quantities = {item.product_id: item.quantity for item in cart.items.all()} return JsonResponse({'quantities': quantities}) except Cart.DoesNotExist: return JsonResponse({'status': 'error', 'message': 'Cart not found'}) else: return JsonResponse({'status': 'error', 'message': 'User not authenticated'})
我的脚本代码(JavaScript)
function updateCartItem(cartId, cartItemId, quantityToAdd, csrftoken) { fetch(`/api/carts/${cartId}/items/${cartItemId}/`, { method: "PATCH", headers: { "Content-Type": "application/json", "X-CSRFToken": csrftoken, }, body: JSON.stringify({ quantity: quantityToAdd, }), }) .then((response) => response.json()) .then((data) => { console.log("Cart successfully updated:", data); updateCartQuantity(); updateItemQuantity(); }); } function updateItemQuantity() { fetch("/get_item_quantity/") .then((response) => response.json()) .then((data) => { if (data.status === 'error') { console.error(data.message); } else { document.getElementById("item-quantity") } }) .catch((error) => { console.error(error); }); } window.addEventListener("load", updateItemQuantity);
HTML代码片段(Django模板)
{% for item in items %} <svg class="icon--cart update-cart" data-product="{{item.product.id}}" data-action="add"> <use href="/media/sprite.svg#plus-solid"/> </svg> <span id="item-quantity{{item.product.id}}" class="quantity">{{item.quantity}}</span> <svg class="icon--cart update-cart" data-product="{{item.product.id}}" data-action="remove"> <use href="/media/sprite.svg#minus-solid"/> </svg> {% endfor %}
解决方案
核心问题在于updateItemQuantity函数中缺少实际更新DOM的逻辑。每个商品数量的span元素ID是item-quantity{{item.product.id}},对应后端返回的quantities字典里的product_id键,只需遍历数据并更新对应元素即可:
修改后的updateItemQuantity函数:
function updateItemQuantity() { fetch("/get_item_quantity/") .then((response) => response.json()) .then((data) => { if (data.status === 'error') { console.error(data.message); } else { // 遍历所有商品数量数据,更新对应DOM元素 for (const productId in data.quantities) { const quantityElement = document.getElementById(`item-quantity${productId}`); if (quantityElement) { quantityElement.textContent = data.quantities[productId]; } } } }) .catch((error) => { console.error(error); }); }
额外优化建议
如果你的PATCH请求返回的响应包含当前修改的商品ID和最新数量,可以直接用该数据更新对应元素,无需重新请求所有商品数量,提升性能:
function updateCartItem(cartId, cartItemId, quantityToAdd, csrftoken) { fetch(`/api/carts/${cartId}/items/${cartItemId}/`, { method: "PATCH", headers: { "Content-Type": "application/json", "X-CSRFToken": csrftoken, }, body: JSON.stringify({ quantity: quantityToAdd, }), }) .then((response) => response.json()) .then((data) => { console.log("Cart successfully updated:", data); updateCartQuantity(); // 假设返回的data包含product_id和quantity字段 const quantityElement = document.getElementById(`item-quantity${data.product_id}`); if (quantityElement) { quantityElement.textContent = data.quantity; } // 无需再调用updateItemQuantity() }); }
内容的提问来源于stack exchange,提问作者David Henson
相关产品推荐
相关产品推荐

