下面我将为您提供一个完整的、可运行的示例,并详细解释每一步的实现原理。

(图片来源网络,侵删)
最终效果预览
我们将创建一个购物车表格,每一行商品都有数量加减按钮,并可以实时计算小计和总计。
第一步:HTML 结构
我们需要一个表格,关键在于为数量输入框和加减按钮设置合适的 class 或 data-* 属性,以便 jQuery 能够精确地定位它们。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">jQuery 表格数量加减示例</title>
<style>
/* 为了美观,添加一些基本样式 */
table {
width: 100%;
border-collapse: collapse;
font-family: Arial, sans-serif;
}
th, td {
border: 1px solid #ddd;
padding: 12px;
text-align: center;
}
th {
background-color: #f2f2f2;
}
.quantity-controls {
display: flex;
align-items: center;
justify-content: center;
gap: 10px; /* 按钮和输入框之间的间距 */
}
.qty-btn {
width: 30px;
height: 30px;
border: 1px solid #ccc;
background-color: #f0f0f0;
cursor: pointer;
font-size: 18px;
line-height: 28px;
border-radius: 4px;
}
.qty-btn:hover {
background-color: #e0e0e0;
}
.qty-input {
width: 60px;
text-align: center;
padding: 5px;
border: 1px solid #ccc;
border-radius: 4px;
}
.total-price {
font-weight: bold;
color: #d9534f;
font-size: 1.2em;
}
</style>
</head>
<body>
<h1>我的购物车</h1>
<table id="cart-table">
<thead>
<tr>
<th>商品</th>
<th>单价</th>
<th>数量</th>
<th>小计</th>
</tr>
</thead>
<tbody>
<!-- 第一行商品 -->
<tr>
<td>苹果 iPhone 15</td>
<td class="unit-price">5999</td>
<td>
<div class="quantity-controls">
<button class="qty-btn decrease">-</button>
<input type="number" class="qty-input" value="1" min="1">
<button class="qty-btn increase">+</button>
</div>
</td>
<td class="subtotal">5999</td>
</tr>
<!-- 第二行商品 -->
<tr>
<td>MacBook Pro</td>
<td class="unit-price">12999</td>
<td>
<div class="quantity-controls">
<button class="qty-btn decrease">-</button>
<input type="number" class="qty-input" value="1" min="1">
<button class="qty-btn increase">+</button>
</div>
</td>
<td class="subtotal">12999</td>
</tr>
<!-- 第三行商品 -->
<tr>
<td>AirPods Pro</td>
<td class="unit-price">1899</td>
<td>
<div class="quantity-controls">
<button class="qty-btn decrease">-</button>
<input type="number" class="qty-input" value="2" min="1">
<button class="qty-btn increase">+</button>
</div>
</td>
<td class="subtotal">3798</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="3" style="text-align: right;">总计:</td>
<td class="total-price">22796</td>
</tr>
</tfoot>
</table>
<!-- 引入 jQuery 库 -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- 我们的 jQuery 代码 -->
<script>
// ... 代码将在下一步添加 ...
</script>
</body>
</html>
关键点解释:
class="qty-btn": 用于所有加减按钮。class="decrease"和class="increase": 用于区分减号和加号按钮。class="qty-input": 用于数量输入框。class="unit-price": 用于存储单价的单元格。class="subtotal": 用于显示小计的单元格。class="total-price": 用于显示总计的单元格。
第二步:jQuery 逻辑实现
我们在 <script> 标签内编写 jQuery 代码来实现功能。

(图片来源网络,侵删)
$(document).ready(function() {
// 1. 定义一个函数来更新单行的小计和整个表格的总计
function updateTotals() {
let grandTotal = 0;
// 遍历表格的每一行 (tbody 里的 tr)
$('#cart-table tbody tr').each(function() {
const $row = $(this); // 使用 $ 前缀表示 jQuery 对象,这是一个好习惯
// 获取当前行的单价和数量
const unitPrice = parseFloat($row.find('.unit-price').text());
const quantity = parseInt($row.find('.qty-input').val());
// 计算小计
const subtotal = unitPrice * quantity;
// 更新当前行的小计单元格
$row.find('.subtotal').text(subtotal);
// 累加到总计
grandTotal += subtotal;
});
// 更新表格底部的总计
$('.total-price').text(grandTotal);
}
// 2. 为所有增加按钮绑定点击事件
$('.increase').on('click', function() {
// 'this' 指的是被点击的按钮元素
const $input = $(this).siblings('.qty-input'); // 找到同级的输入框
let val = parseInt($input.val());
val++; // 数量加 1
$input.val(val); // 更新输入框的值
updateTotals(); // 调用更新函数
});
// 3. 为所有减少按钮绑定点击事件
$('.decrease').on('click', function() {
const $input = $(this).siblings('.qty-input');
let val = parseInt($input.val());
// 数量不能小于 1 (min="1" 属性提供了基础保障)
if (val > 1) {
val--; // 数量减 1
$input.val(val);
updateTotals(); // 调用更新函数
}
});
// 4. 为数量输入框绑定 change 事件(当用户手动输入并失去焦点时触发)
$('.qty-input').on('change', function() {
let val = parseInt($(this).val());
// 防止输入非数字或小于 1 的值
if (isNaN(val) || val < 1) {
$(this).val(1); // 如果输入无效,则重置为 1
}
updateTotals(); // 调用更新函数
});
// 页面加载时,执行一次更新,确保初始状态正确
updateTotals();
});
代码逻辑详解
-
updateTotals()函数:- 这是核心功能,负责重新计算所有金额。
let grandTotal = 0;初始化一个变量来存储总计金额。$('#cart-table tbody tr').each(function() { ... });遍历<tbody>中的每一行,jQuery 的.each()方法非常适合这种迭代操作。const $row = $(this);获取当前正在处理的行的 jQuery 对象。$row.find('.unit-price').text(): 在当前行内查找class为unit-price的元素,并获取其文本内容("5999")。parseFloat(): 将字符串转换为浮点数,因为我们需要用它进行数学计算。parseInt(): 将字符串转换为整数,用于数量。subtotal = unitPrice * quantity;计算小计。$row.find('.subtotal').text(subtotal);将计算好的小计更新到当前行的小计单元格中。grandTotal += subtotal;将当前行的小计累加到总金额上。- 循环结束后,
$('.total-price').text(grandTotal);将最终计算出的总金额更新到表格底部的总计单元格。
-
$('.increase').on('click', ...):- 为所有
class为increase的元素(即所有 按钮)绑定点击事件。 $(this).siblings('.qty-input'): 这是关键一步。this指代被点击的按钮,.siblings()方法查找与该按钮拥有相同父元素(即div.quantity-controls)的兄弟元素,并筛选出class为qty-input的那个,这样就精确地找到了与当前按钮关联的数量输入框。- 后续的逻辑就是获取输入框的值,加一,然后更新输入框的值,并调用
updateTotals()来刷新所有金额。
- 为所有
-
$('.decrease').on('click', ...):- 与增加按钮逻辑类似,只是将数量减一,并增加了一个判断
if (val > 1)来确保数量不会小于 1。
- 与增加按钮逻辑类似,只是将数量减一,并增加了一个判断
-
$('.qty-input').on('change', ...):
(图片来源网络,侵删)- 这个事件处理了用户直接在输入框里输入数字的情况。
change事件在输入框失去焦点(比如用户点击别处)且值发生改变时触发。- 这里我们做了一次输入验证,如果用户输入了无效的数字(如 "abc" 或 "0"),我们会自动将其重置为 "1"。
- 最后同样调用
updateTotals()来同步更新价格。
总结与扩展
这个示例提供了一个非常健壮和用户友好的解决方案,您可以根据这个基础进行扩展:
- AJAX 保存到后端: 在
updateTotals()函数中,可以加入 AJAX 请求,将最新的购物车数据(商品ID和数量)发送到服务器进行保存。 - 删除商品行: 为每一行添加一个“删除”按钮,点击后移除该行
<tr>,并调用updateTotals()。 - 更复杂的计算: 如果涉及折扣、税费等,只需在
updateTotals()函数中添加相应的计算逻辑即可。 - 动画效果: 可以使用 jQuery 的
.fadeTo()或.slideUp()等方法为价格变化或行删除添加平滑的动画效果,提升用户体验。
