当前位置: 首页 > article >正文

js实现购物车功能

将数据渲染到页面上

然后先将格式写出来,分析得出是由一个tr包4个td组成的,将表头用thead包起来,后面写tbody将内容包起来后面的两个td内分别包了两个按钮,最后面有3个输入框和2个按钮(确认和取消),样式要写为display:none

然后将数据以数组包对象的形式写在json文件内

[{
		"id": "1",
		"name": "包子",
		"price": "2",
		"num": "0"
	},
	{
		"id": "2",
		"name": "油条",
		"price": "3",
		"num": "0"
	},
	{
		"id": "3",
		"name": "鸡蛋",
		"price": "1.5",
		"num": "0"
	},
	{
		"id": "4",
		"name": "胡辣汤",
		"price": "3",
		"num": "0"
	},
	{
		"id": "5",
		"name": "小米粥",
		"price": "1",
		"num": "0"
	}
]

我们先将要用到的都获取过来,并且将data的作用域提到全局,并且每次添加的时候都是在id后面添加,设置一个最大的id为数据内在最大的id(确保唯一性),ee

			let data;
			let max_ID;
			// 获取弹窗
			let alerts = document.getElementById('ti_body');
			// 获取删除
			let dlt = document.getElementsByClassName('delete');
			// 获取数量+
			let append = document.getElementsByClassName('append');
			// 获取数量-
			let reduce = document.getElementsByClassName('reduce');
			// 获取tbody
			let tbody = document.getElementById('goods');
			// 获取三个添加时的输入框
			let addname = document.getElementById('name');
			let addprice = document.getElementById('price');
			let addnum = document.getElementById('number');
			// 获取三个编辑是的输入框
			let addnames = document.getElementById('names');
			let addprices = document.getElementById('prices');
			let addnums = document.getElementById('numbers');
			// 获取添加按钮
			let add = document.getElementsByClassName('add')[0];
			// 添加输入框区域
			let content = document.getElementsByClassName('content')[0];
			// 编辑输入框区域
			let contents = document.getElementsByClassName('contents')[0];
			// 取消按钮
			let off = document.getElementsByClassName('off')[0];
			// 获取商品数量
			let how = document.getElementsByClassName('how')[0];
			// 总价框
			let total = document.getElementById('total');
			// 总数量框
			let tot = document.getElementById('tot');
			// 获取json文件
			let xhr = new XMLHttpRequest();
			xhr.open('get', 'js/new_file.json', true);
			xhr.send();
			xhr.onreadystatechange = function() {
				if (xhr.readyState == 4 && xhr.status == 200) {
					let text = xhr.responseText;
					console.log(text);
					data = JSON.parse(text);
					max_ID = data[data.length - 1].id
					console.log(max_ID);
					console.log(data);
					render(data);
				}
			};

 将数据渲染到页面上,以字符串拼接的形式

			function render(data) {
				let str = ``;
				let num = 0;
				let count = 0;
				for (let i = 0; i < data.length; i++) {
					str += `<tr>
					<td>${data[i].name}</td>
					<td>${data[i].price}</td>
					<td><button class="reduce" onclick="cut_num(${i})">-</button> <span class="how">${data[i].num}</span> <button class="append" onclick="add_num(${i})">+</button>
					</td>
					<td><button class="edit" onclick="edit(${i})">编辑</button><button class="delete" onclick="del(${i})" >删除</button></td>
				</tr>`;
					num += data[i].num * 1;
					count += data[i].num * data[i].price;
				}
				total.innerHTML = count;
				tot.innerHTML = num;
				tbody.innerHTML = str;

			};

 然后给按钮+绑定点击事件,当每次点击时,对应的下标index的num++

function add_num(index) {
				data[index].num++;
				render(data);
			};

  然后给按钮-绑定点击事件,当每次点击时,对应的下标index的num--

function cut_num(index) {
				if (data[index].num > 0) {
					data[index].num--;
					render(data);
				};
			};

 点击删除时,运用splice的方法,从对应下标删除,并且删除一个

function del(index) {
				data.splice(index, 1);
				render(data);
			};

 点击添加的时候,应该先将隐藏的输入框和按钮显示出来,并且清空里面的值

	function add_show() {
				content.style.display = 'block'
				addname.value = '';
				addprice.value = '';
				addnum.value = '';
			};

 当点击取消时再将他们隐藏起来

function add_off() {
				content.style.display = 'none'
			}

 接下来写确定添加的点击事件,按实际情况来说的话,我们商品名称不能为空;并且商品价格不能为空,不能小于0;商品数量不能为空,不能小于0,商品的价格不能为空,不能小于0,并且是整数,如果不符合条件的话弹出弹窗提示用户,所以我们的添加的点击事件要写判断,并且添加时使最大的id++,渲染完成后再让输入框和按钮隐藏

判断如下:

// 添加确定
			function add_confirm() {
				// 判断,如果第一个name输入框内为空返回弹窗
				if (addname.value == "") {
					alerts.style.top = `0`
					alerts.innerHTML = `输入无效,请输入一个商品!`
					setTimeout(function() {
						alerts.style.top = `-10%`
					}, 3000)
					// 如果第二个为空或者数字小于0时返回弹窗
				} else if (addprice.value == "" || addprice.value < 0) {
					alerts.style.top = `0`
					alerts.innerHTML = `输入无效,请输入一个数字!`
					setTimeout(function() {
						alerts.style.top = `-10%`
					}, 3000)
					// 如果数量为空,并且小于0,并且当他不为整数时返回弹窗
				} else if (addnum.value == "" || addnum.value < 0 || addnum.value % 1 != 0) {
					alerts.style.top = `0`
					alerts.innerHTML = `输入无效,请输入一个数字!`
					setTimeout(function() {
						alerts.style.top = `-10%`
					}, 3000)
				} else {
					max_ID++;
					data.push({
						id: max_ID,
						name: addname.value,
						price: addprice.value,
						num: addnum.value
					})
					console.log(data);
					render(data);
					content.style.display = 'none';
				}
			}

 编辑按钮点击的时候,我们应该获取到他在哪一行,并且获取哪一行的数据,将数据传递到输入框内,并且将这个id存起来

	function edit(i) {
				addnames.value = data[i].name;
				addprices.value = data[i].price;
				addnums.value = data[i].num;
				sessionStorage.setItem('edit_id', data[i].id)
				contents.style.display = 'block';
			};

 当我们编辑点确定的时候也需要判断,判断条件和上面的相同,如果所有的格式没有问题,那么将json中的id遍历一下,看看能不能找到和上面我们存的id相同,相同的话,再将内容进行替换并且重新渲染就好了

还有一种情况,我们点编辑后将这一条数据删除了,那么我们应该返回编辑失败

这种就先声明一个变量为false,当他在数据内能找到找个id将他变为true,这样就可以显示渲染,如果找不到那么就还是false,下面判断,如果当这个变量为false时,那么就返回弹窗,最后渲染时再将输入框隐藏即可

// 编辑判断
			function add_confirms() {
				if (addnames.value == "") {
					alerts.style.top = `0`
					alerts.innerHTML = `输入无效,请输入一个商品!`
					setTimeout(function() {
						alerts.style.top = `-10%`
					}, 3000)
				} else if (addprices.value == "" || addprices.value < 0) {
					alerts.style.top = `0`
					alerts.innerHTML = `输入无效,请输入一个数字!`
					setTimeout(function() {
						alerts.style.top = `-10%`
					}, 3000)
				} else if (addnums.value == "" || addnums.value < 0 || addnums.value % 1 != 0) {
					alerts.style.top = `0`
					alerts.innerHTML = `输入无效,请输入一个数字!`
					setTimeout(function() {
						alerts.style.top = `-10%`
					}, 3000)
				} else {
					let a = false;
					for (let i = 0; i < data.length; i++) {
						if (data[i].id == sessionStorage.getItem('edit_id')) {
							data[i].name = addnames.value;
							data[i].price = addprices.value;
							data[i].num = addnums.value;
							a = true;
							break;
						}
					}
					if (a == false) {
						alerts.style.top = `0`
						alerts.innerHTML = `编辑失败!`
						setTimeout(function() {
							alerts.style.top = `-10%`
						}, 3000)
					}
					contents.style.display = 'none';
					render(data);
				}
			};

下面是全部的代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title></title>
	</head>
	<style>
		#ti_body {
			top: -10%;
			left: 45vw;
			width: auto;
			height: 40px;
			background-color: red;
			color: white;
			text-align: center;
			line-height: 40px;
			padding: 3px 30px;
			border-radius: 0.25rem;
			position: fixed;
			z-index: 999;
			display: flex;
			justify-content: space-between;
		}
	</style>
	<body>
		<table border="1px" cellpadding="10px" style="border-collapse: collapse;">
			<thead>
				<tr>
					<th>商品名称</th>
					<th>商品价格(单位为元)</th>
					<th>商品数量</th>
					<th>操作</th>
				</tr>
			</thead>
			<tbody id="goods" style="text-align: center;">
				<tr>
					<td></td>
					<td>28</td>
					<td><button class="reduce">-</button> <span class="how">0</span> <button class="append">+</button>
					</td>
					<td><button class="edit">编辑</button><button class="delete">删除</button></td>
				</tr>
			</tbody>
			<footer>
				<tr style="text-align: center;">
					<td>总价:</td>
					<td id="total"></td>
					<td>总数量:</td>
					<td id="tot"></td>
				</tr>
			</footer>
		</table>
		<button class="add" onclick="add_show()">添加</button>
		<div style="display: none;" class="content">
			<input type="text" placeholder="请输入商品名称" id="name" />
			<input type="number" placeholder="请输入商品价格" id="price" />
			<input type="number" placeholder="请输入商品数量" id="number" />
			<br />
			<button onclick="add_confirm()">确认</button>
			<button class="off" onclick="add_off()">取消</button>
		</div>
		<div style="display: none;" class="contents">
			<input type="text" placeholder="请输入商品名称" id="names" />
			<input type="number" placeholder="请输入商品价格" id="prices" />
			<input type="number" placeholder="请输入商品数量" id="numbers" />
			<br />
			<button onclick="add_confirms()">确认</button>
			<button class="off" onclick="add_offs()">取消</button>
		</div>
		<div id="ti_body">
			<div id="ti_content">
				成功提示的文案
			</div>
			<div id="over" onclick="cancel()">×</div>
		</div>
		<script>
			let data;
			let max_ID;
			// 获取弹窗
			let alerts = document.getElementById('ti_body');
			// 获取删除
			let dlt = document.getElementsByClassName('delete');
			// 获取数量+
			let append = document.getElementsByClassName('append');
			// 获取数量-
			let reduce = document.getElementsByClassName('reduce');
			// 获取tbody
			let tbody = document.getElementById('goods');
			// 获取三个添加时的输入框
			let addname = document.getElementById('name');
			let addprice = document.getElementById('price');
			let addnum = document.getElementById('number');
			// 获取三个编辑是的输入框
			let addnames = document.getElementById('names');
			let addprices = document.getElementById('prices');
			let addnums = document.getElementById('numbers');
			// 获取添加按钮
			let add = document.getElementsByClassName('add')[0];
			// 添加输入框区域
			let content = document.getElementsByClassName('content')[0];
			// 编辑输入框区域
			let contents = document.getElementsByClassName('contents')[0];
			// 取消按钮
			let off = document.getElementsByClassName('off')[0];
			// 获取商品数量
			let how = document.getElementsByClassName('how')[0];
			// 总价框
			let total = document.getElementById('total');
			// 总数量框
			let tot = document.getElementById('tot');
			// 获取json文件
			let xhr = new XMLHttpRequest();
			xhr.open('get', 'js/new_file.json', true);
			xhr.send();
			xhr.onreadystatechange = function() {
				if (xhr.readyState == 4 && xhr.status == 200) {
					let text = xhr.responseText;
					console.log(text);
					data = JSON.parse(text);
					max_ID = data[data.length - 1].id
					console.log(max_ID);
					console.log(data);
					render(data);
				}
			};
			// 渲染函数
			function render(data) {
				let str = ``;
				let num = 0;
				let count = 0;
				for (let i = 0; i < data.length; i++) {
					str += `<tr>
					<td>${data[i].name}</td>
					<td>${data[i].price}</td>
					<td><button class="reduce" onclick="cut_num(${i})">-</button> <span class="how">${data[i].num}</span> <button class="append" onclick="add_num(${i})">+</button>
					</td>
					<td><button class="edit" onclick="edit(${i})">编辑</button><button class="delete" onclick="del(${i})" >删除</button></td>
				</tr>`;
					num += data[i].num * 1;
					count += data[i].num * data[i].price;
				}
				total.innerHTML = count;
				tot.innerHTML = num;
				tbody.innerHTML = str;

			};
			console.log(max_ID);
			// 添加次数
			function add_num(index) {
				data[index].num++;
				render(data);
			};
			// 减少
			function cut_num(index) {
				if (data[index].num > 0) {
					data[index].num--;
					render(data);
				};
			};
			// 删除
			function del(index) {
				data.splice(index, 1);
				render(data);
			};
			// 添加显示
			function add_show() {
				content.style.display = 'block'
				addname.value = '';
				addprice.value = '';
				addnum.value = '';
			};
			// 取消
			function add_off() {
				content.style.display = 'none'
			}

			function add_offs() {
				contents.style.display = 'none'
			}

			// 添加确定
			function add_confirm() {
				// 判断,如果第一个name输入框内为空返回弹窗
				if (addname.value == "") {
					alerts.style.top = `0`
					alerts.innerHTML = `输入无效,请输入一个商品!`
					setTimeout(function() {
						alerts.style.top = `-10%`
					}, 3000)
					// 如果第二个为空或者数字小于0时返回弹窗
				} else if (addprice.value == "" || addprice.value < 0) {
					alerts.style.top = `0`
					alerts.innerHTML = `输入无效,请输入一个数字!`
					setTimeout(function() {
						alerts.style.top = `-10%`
					}, 3000)
					// 如果数量为空,并且小于0,并且当他不为整数时返回弹窗
				} else if (addnum.value == "" || addnum.value < 0 || addnum.value % 1 != 0) {
					alerts.style.top = `0`
					alerts.innerHTML = `输入无效,请输入一个数字!`
					setTimeout(function() {
						alerts.style.top = `-10%`
					}, 3000)
				} else {
					max_ID++;
					data.push({
						id: max_ID,
						name: addname.value,
						price: addprice.value,
						num: addnum.value
					})
					console.log(data);
					render(data);
					content.style.display = 'none';
				}
			}
			// 编辑效果
			function edit(i) {
				addnames.value = data[i].name;
				addprices.value = data[i].price;
				addnums.value = data[i].num;
				sessionStorage.setItem('edit_id', data[i].id)
				contents.style.display = 'block';
			};
			// 编辑判断
			function add_confirms() {
				if (addnames.value == "") {
					alerts.style.top = `0`
					alerts.innerHTML = `输入无效,请输入一个商品!`
					setTimeout(function() {
						alerts.style.top = `-10%`
					}, 3000)
				} else if (addprices.value == "" || addprices.value < 0) {
					alerts.style.top = `0`
					alerts.innerHTML = `输入无效,请输入一个数字!`
					setTimeout(function() {
						alerts.style.top = `-10%`
					}, 3000)
				} else if (addnums.value == "" || addnums.value < 0 || addnums.value % 1 != 0) {
					alerts.style.top = `0`
					alerts.innerHTML = `输入无效,请输入一个数字!`
					setTimeout(function() {
						alerts.style.top = `-10%`
					}, 3000)
				} else {
					let a = false;
					for (let i = 0; i < data.length; i++) {
						if (data[i].id == sessionStorage.getItem('edit_id')) {
							data[i].name = addnames.value;
							data[i].price = addprices.value;
							data[i].num = addnums.value;
							a = true;
							break;
						}
					}
					if (a == false) {
						alerts.style.top = `0`
						alerts.innerHTML = `编辑失败!`
						setTimeout(function() {
							alerts.style.top = `-10%`
						}, 3000)
					}
					contents.style.display = 'none';
					render(data);
				}
			};
		</script>
	</body>
</html>


http://www.kler.cn/a/403398.html

相关文章:

  • n、nvm、nrm、pnpm、yarn各种指令大全
  • 计算字符串的MD5
  • 量子感知机
  • C#(11) 运算符重载
  • 设计模式之 状态模式
  • 操作系统大会2024 | 麒麟信安根植openEuler社区,持续技术创新 共拓新应用 探索新机遇
  • Qt问题:不同文件中相同命名空间的多个 Q_NAMESPACE
  • ThinkPHP框架和Laravel框架区别
  • pytorch训练的双卡,一个显卡占有20GB,另一个卡占有8GB,怎么均衡?
  • Elasticsearch面试内容整理-核心概念与数据模型
  • K8S基础概念和环境搭建
  • Flink基础面试题
  • Excel - VLOOKUP函数将指定列替换为字典值
  • 信息与网络安全
  • Java数据库连接(Java Database Connectivity,JDBC)
  • 使用chrome 访问虚拟机Apache2 的默认页面,出现了ERR_ADDRESS_UNREACHABLE这个鸟问题
  • unity3d————范围检测
  • 实现金蝶云与MySQL的无缝数据集成
  • 通过声纹或者声波来切分一段音频
  • nwjs崩溃复现、 nwjs-控制台手动操纵、nwjs崩溃调用栈解码、剪切板例子中、nwjs混合模式、xdotool显示nwjs所有进程窗口列表
  • ubuntu用bind9自建DNS服务器时logging日志出现failed: permission denied解决方法
  • CTFL(六)测试工具
  • QT 自定义界面布局要诀
  • windows C#-异步编程模型(上)
  • MySQL45讲 第二十七讲 主库故障应对:从库切换策略与 GTID 详解——阅读总结
  • strcpy的模拟实现(c基础)