You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 16:17:39