实现一个简单的购物车功能的思路其实是比较基础的,主要包括:添加商品到购物车、删除商品、更新商品数量、计算总价等基本功能。以下是实现购物车功能的基本思路和结构。
需求分析
一个基本的购物车功能需要支持以下功能:
- 添加商品:用户可以选择商品,并将商品加入购物车。
- 展示购物车:显示购物车内所有商品的列表,包括商品名称、数量、单价、总价等。
- 更新商品数量:用户可以修改商品的数量。
- 删除商品:用户可以从购物车中删除商品。
- 计算总价:购物车中所有商品的总价应随商品数量、价格变化而实时更新。
- 清空购物车:用户可以清空购物车中的所有商品。
添加商品:点击出现
以下是一个简单的购物车小代码(无json数据,需自己写一份,然后更改代码里面部分数据)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>购物车</title>
<style>
td {
text-align: center;
}
div {
display: none;
}
</style>
</head>
<body>
<h4>基础购物车</h4>
<table border="1" cellspacing="0">
<thead>
<tr>
<th>商品名称</th>
<th>商品价格(单位为元)</th>
<th>商品数量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!-- 渲染 -->
</tbody>
<tfoot>
<tr>
<th>总价:</th>
<td class="n"></td>
<th>总数量:</th>
<td class="u"></td>
</tr>
</tfoot>
</table>
<!-- 添加商品按钮 -->
<button onclick="add()">添加</button>
<!-- 添加输入框 -->
<div class="items">
<!-- 产品名输入框 -->
<input type="text" id="names" />
<!-- 价格输入框 -->
<input type="number" id="pri" />
<!-- 数量输入框 -->
<input type="number" id="scalar" />
<br />
<button class="sure" onclick="sur()">确定</button>
<button class="cancel" onclick="cel()">取消</button>
</div>
<!-- 编辑按钮输入框 -->
<div class="box">
<!-- 产品名输入框 -->
<input type="text" id="sign" />
<!-- 价格输入框 -->
<input type="number" id="rate" />
<!-- 数量输入框 -->
<input type="number" id="fund" />
<br />
<button class="sur" onclick="yes()">确定</button>
<button class="cc" onclick="re()">取消</button>
</div>
<script>
let data;
let maxID;
// 获取tbody
let tnt = document.getElementsByTagName('tbody')[0];
// 获取总价总数量,.n .u为下标
let footTotalPrice = document.querySelector('tfoot .n');
let footTotalNum = document.querySelector('tfoot .u');
// 获取输入框确定取消按钮的div
let items = document.getElementsByClassName('items')[0];
// 获取数据
let shop = new XMLHttpRequest();
shop.open('get', 'js/index.json', true);
shop.send();
shop.onreadystatechange = function() {
if (shop.readyState == 4 && shop.status == 200) {
let text = shop.responseText;
data = JSON.parse(text);
console.log(data);
ran(data);
}
};
// JSON数据渲染到页面里
function ran(data) {
let str = "";
// 声明总数总价
let totalp = 0;
let totaln = 0;
for (let i = 0; i < data.length; i++) {
str += `
<tr>
<td>${data[i].name}</td>
<td>${data[i].price}</td>
<td>
<button class="plus">+</button>
<span>${data[i].num}</span>
<button class="min">-</button>
</td>
<td>
<button class="edit" onclick="edit(${i})">编辑</button>
<button class="delete" data-index="${i}">删除</button>
</td>
</tr>
`;
// 计算总价格
totalp += data[i].price * data[i].num;
// 计算总数量
totaln += data[i].num;
}
// 内容插入到页面里
tnt.innerHTML = str;
// 更新总价和总数量
footTotalPrice.textContent = totalp.toFixed(2);
footTotalNum.textContent = totaln;
// 调用添加事件函数
del();
// 调用数量加减函数
quan();
}
// 删除事件
function del() {
//获取删除按钮
let debun = document.querySelectorAll('.delete');
debun.forEach(button => {
// 绑定事件监听
button.addEventListener('click', function() {
// 获取按钮属性名的值
let index = this.getAttribute('data-index');
// 删除指定下标值
data.splice(index, 1);
// 调用渲染函数
ran(data);
});
});
}
// 数量加减
function quan() {
let plusbut = document.querySelectorAll('.plus');
let minbut = document.querySelectorAll('.min');
plusbut.forEach(button => {
// 绑定事件监听
button.addEventListener('click', function() {
// row获取当前按钮所在的表格行
let row = this.closest('tr');
// 找到当前行在其父元素(表格)中的位置
let index = Array.from(row.parentNode.children).indexOf(row);
// 增加对应数据的数量
data[index].num++;
// 调用渲染函数
ran(data);
});
});
minbut.forEach(button => {
// 绑定事件监听
button.addEventListener('click', function() {
// 获取当前按钮所在的表格行
let row = this.closest('tr');
// 找到当前行在其父元素中的位置
let index = Array.from(row.parentNode.children).indexOf(row);
// 判断如果数量大于0,则减少对应数据的数量
if (data[index].num > 0) {
data[index].num--;
ran(data);
}
});
});
}
// 获取输入框
let names = document.getElementById('names');
let pri = document.getElementById('pri');
let scalar = document.getElementById('scalar');
// 获取确定取消按钮
let sure = document.getElementsByClassName('sure');
let cancel = document.getElementsByClassName('cancel');
// 添加事件
function add() {
names.value = '';
pri.value = '';
scalar.value = '';
items.style.display = 'block';
}
// 点击确定
function sur() {
let name = names.value;
// 转换浮点型,数字转换带小数点
let price = parseFloat(pri.value);
// 转换整数
let num = parseInt(scalar.value);
if (name && !isNaN(price) && !isNaN(num) && num > 0) {
// 最大id
maxID++;
data.push({
id: maxID,
name: name,
price: price,
num: num
});
// 调用渲染函数
ran(data);
// 确定输入框隐藏
items.style.display = 'none';
} else {
alert('出错了,再试试');
}
}
// 点击取消
function cel() {
items.style.display = 'none';
}
// 编辑事件
// 获取编辑事件div
let box = document.getElementsByClassName('box')[0];
// 获取input名字框
let sign = document.getElementById('sign');
// 数量
let rate = document.getElementById('rate');
// 价格
let fund = document.getElementById('fund');
// 获取确定取消按钮
let sures = document.getElementsByClassName('sur')[0];
let cc = document.getElementsByClassName('cc')[0];
// 编辑按钮设置点击事件
function edit(i) {
console.log(i);
box.style.display = 'block';
sign.value = data[i].name;
rate.value = data[i].price;
fund.value = data[i].num
sessionStorage.setItem('id', data[i].id)
}
// 编辑确定
function yes() {
let name = sign.value;
let price = parseFloat(rate.value);
let num = parseInt(fund.value);
if (name && !isNaN(price) && !isNaN(num) && num > 0) {
let id = sessionStorage.getItem('id');
for (let item in data) {
if (data[item].id == id) {
data[item].name = name;
data[item].price = price;
data[item].num = num;
}
}
// 调用渲染函数
ran(data)
}
}
// 点击取消
function re() {
box.style.display = 'none';
}
</script>
</body>
总结
这只是一个简单的购物车功能实现思路。如果要扩展功能,还可以考虑如下改进:
- 商品存储:将购物车数据保存在本地存储 (localStorage) 或后端数据库,以便用户下次访问时还能够看到购物车的内容。
- 结算功能:添加结算按钮,跳转到结算页面,展示配送信息、支付方式等。
- 优惠券和折扣:可以增加优惠券、折扣计算的功能。
- 商品选择:可以增加选择商品、批量删除、选择所有商品等功能。
这个简单的购物车功能为理解和实现更复杂的购物车系统提供了一个基础思路。