一期测试项目:基于JavaScript的JSON数组的购物车项目

1.分析要求模块

//基本功能模块:(已完成)
	//json数组已给出!通过json数组实现一下功能:
			 //实现购物车的添加:
			 //每次点击商品行添加按钮时:
				//1.采购详情表单已存在该行,数量实现自动加一
				//2.采购详情表单不存在该行,创建商品行

			 //实现购物车的删除:
			 //当点击采购详情表单行中的删除按钮时,弹出“确定要删除吗”提示
				//1.“确定” 删除
				//2.“取消” 不删除
			 
			 //计算总结:
				//每次添加商品之后,商品总计都要进行更新。

	//待完善的功能模块:(必要,待完成)(已完成)
			 //判断进价:
				//如果超过单价,则提示信息 不进行操作 (以上已完成)
			 
			 //判断输入数量:
			 //1.输入框输入时:
			 //购买数量不能超过库存数量 否则会弹出提示信息 (以上已完成)
			 //每次购买数量加一,库存数量减一 (以上已完成)
			 //库存数量减少到0,提示库存信息为空,无法再购买。 (以上已完成)
			 //2.点击添加按钮增加数量时:
			 //当点击添加时,每进行一次增加,库存数量都做相应的减少 
			 //当库存为空时,点击商品库存信息表单添加的按钮时:
				//1:提示信息
				//2:再次点击添加按钮时,采购详情表单行不执行任何操作

	//其他的功能模块:(非必要,待完成)
			 //输入框实现“+”“-”按钮功能 
			 //每次点击 输入框数量变化 小计变化 总计变化。。。。。等等吧

2.代码实现模块

需要源码的小伙伴可前往资源:前端开发经典项目:《基于JavaScript的JSON数组的购物车项目》进行下载!


<!DOCTYPE HTML>
<html>
	<head>
		<meta charset="utf-8"/>
		<title> 购物车 </title>
		<style type="text/css">
			fieldset{
				width:800px;
				margin:0px auto;
			}
		
		</style>
	</head>

	<body>
		<!-- 商品库存信息 -->
		<fieldset>
			<legend>商品库存信息</legend>
			<table border="1" width="100%">
				<thead>
					<tr>
						<th>商品编号</th>
						<th>商品名字</th>
						<th>商品单价</th>
						<th>商品类别</th>
						<th>库存余量</th>
						<th>添加操作</th>
					</tr>
				</thead>
				<tbody id="fbody">
					
				</tbody>
			</table>
		<!-- 采购详情 -->
		</fieldset>
		<fieldset>
			<legend>采购详情</legend>
			<table border="1" width="100%">
				<thead>
					<tr>
						<th>商品编号</th>
						<th>商品名字</th>
						<th>供应商</th>
						<th>进价</th>
						<th>购买数量</th>
						<th>小计</th>
						<th>操作</th>
					</tr>
				</thead>
				<tbody id="mybody">
					 
				</tbody>
			</table>
			合计:<span id="total">0</span>元
		</fieldset>


	<script type="text/javascript">
		//商品数组
		var goods= [
			{"goodid":"1000100","goodname":"水杯","goodprice":50,"goodstore":100,"goodtype":"日用品"},
			{"goodid":"1000101","goodname":"毛巾","goodprice":10,"goodstore":10,"goodtype":"日用品"},
			{"goodid":"1000102","goodname":"牙膏","goodprice":10,"goodstore":100,"goodtype":"日用品"},
			{"goodid":"1000103","goodname":"耳机","goodprice":100,"goodstore":10,"goodtype":"电子产品"},
			{"goodid":"1000104","goodname":"手机","goodprice":5000,"goodstore":100,"goodtype":"电子产品"},
			{"goodid":"1000105","goodname":"笔记本电脑","goodprice":5000,"goodstore":10,"goodtype":"电子产品"},
			{"goodid":"1000106","goodname":"鼠标","goodprice":50,"goodstore":10,"goodtype":"电子产品"}
			]
		
		//遍历商品对象数组 将数组信息添加到商品库存信息表中
		for(var i=0;i<goods.length;i++){
			//获取商品对象
			var f=goods[i];
			//创建空字符串 进行拼接
			var tds="";
			tds+="<td>"+f.goodid+"</td>";
			tds+="<td>"+f.goodname+"</td>";
			tds+="<td>"+f.goodprice+"</td>";
			tds+="<td>"+f.goodtype+"</td>";
			tds+="<td>"+f.goodstore+"</td>";
			tds+="<td><input type='button' value='添加到采购' onclick='addGoods(this)'></td>";
				
			//创建tr对象
			var tr=document.createElement("tr");
			tr.innerHTML=tds;
			//将tr添加到商品库存信息fbody中
			fbody.appendChild(tr);
		}
		
		//定义添加函数
		function addGoods(btn){
			//找到添加按钮的行
			var tr=btn.parentElement.parentElement;
			//定义变量 将行元素各项赋值給变量
			var fid=tr.children[0].innerHTML;
			var fname=tr.children[1].innerHTML;
			var fprice=tr.children[2].innerHTML;
			//var fstore=tr.children[4].innerHTML;
			
			//去除添加重复
			if(mybody.children.length>0){
				//遍历商品添加的行元素
				for(var i=0;i<mybody.children.length;i++){
					//定义变量 存储新添加的行元素(mybody的孩子元素)
					var trH=mybody.children[i]; 
					//新添加的行的第一个元素(商品id编号)与商品id编号进行比较
					if(trH.children[0].innerHTML==fid){ 
						/*//id编号相等 数量加一	
						trH.children[4].children[0].value++;*/

						//判断 采购详情表单中的购买数量是否大于数组中的库存数量 若大于则提示信息 
						//若小于库存 每点击添加按钮一次则库存数量做相应的减少 减少到0时提示信息
						//tr 需要被操作的购买详情的行元素
						//遍历数组
						for(var j=0;j<goods.length;j++){
							//定义变量 存储获取到的数组中每一项数据
							var gI=goods[j]; //这里定义good[i],方便下方的条件满足后的进一步条件判断
							//采购详情表单中相应行的id与数组id进行比较
							if(trH.children[0].innerHTML==gI.goodid){  //逐渐加1 先等与再大于,故条件设立在等于(等于时直接跳出条件),然后小于
								//采购详情表单中相应行的数量与数组库存进行比较 大于则提示信息
								if(trH.children[4].children[0].value==gI.goodstore){
									confirm("库存已空,无法再进行添加");
									//刷新小计
									trH.children[5].innerHTML=Number(trH.children[4].children[0].value)*Number(fprice*0.7);
									break;
								//小于等于 则做相应的减少
								}else{
									//id编号相等 数量加一
									trH.children[4].children[0].value++;
									//上表单的库存数量=数组库存总数-下表单的购买数量
									tr.children[4].innerHTML=gI.goodstore-trH.children[4].children[0].value;
									//刷新小计
									trH.children[5].innerHTML=Number(trH.children[4].children[0].value)*Number(fprice*0.7);
									break;
								}
								/*//小计相应增加
								trH.children[5].innerHTML=Number(trH.children[4].children[0].value)*Number(fprice*0.7);*/
							}
						}
						/*//小计相应增加(小计随条件的增加,位置发生改变)
						tr.children[5].innerHTML=Number(tr.children[4].children[0].value)*Number(fprice*0.7);*/
						//刷新总计
						sum();
						return;
					}
				}
				
			}

			/*//去除添加重复
			if(mybody.children.length>0){
				//遍历商品添加的行元素
				for(var i=0;i<mybody.children.length;i++){
					//将新添加的行元素赋值给变量tr
					var tr=mybody.children[i]; 
					//新添加的行的第一个元素(商品id编号)与商品id编号进行比较
					if(tr.children[0].innerHTML==fid){ 
						//id编号相等 数量加一	
						tr.children[4].children[0].value++;

						//小计相应增加
						tr.children[5].innerHTML=Number(tr.children[4].children[0].value)*Number(fprice*0.7);
						//刷新总计
						sum();
						return;
					}
				}
				
			}*/

			//第一次点击添加按钮时 采购详情表单中mybody的children的长度为零,使得商品库存信息表单中的库存不能发生改变
			tr.children[4].innerHTML--;   //!!!! !!第一次运行时数量上表单的库存值不会发生变化,这部可以解决!!!!
			//!!!!且这一步《只》在《第一次》点击添加《某个按钮》时执行,再次点击该按钮的话,将会进入到《去重函数中进行return到结束,不会再回到这里》

			//创建空字符串 进行采购详情表格的拼接
			var tds="";
			tds+="<td>"+fid+"</td>"; //商品id
			tds+="<td>"+fname+"</td>"; //商品名称
			tds+="<td><input type='text'/></td>"; //供应商
			tds+="<td><input type='text' value='"+fprice*0.7+"' onblur='tiShi(this)'/></td>"; //进价=单价*0.7
			tds+="<td><input type='text' value='1' id='shuliang' onblur='changeNumber(this)'/>"+"</td>"; //购买数量
			tds+="<td>"+fprice*0.7+"</td>";  //小计
			tds+="<td><input type='button' value='删除' onclick='delectGoods(this)'></td>";  //操作
			
			//创建tr对象
			var tr2=document.createElement("tr");
			tr2.innerHTML=tds;
			//将tr添加到采购详情表的mybody中
			mybody.appendChild(tr2);
			
			//刷新总计
			sum();
		}

		//定义删除函数 
		function delectGoods(btn){
			// 判断是否确定删除
			if(confirm('确定删除?')){
				//btnQty.parentNode:父级元素td .parentNode td的父级元素tr
				btn.parentNode.parentNode.remove();
				//更新总计
				sum();
			}
		}

		//进价超过单价时 提示信息
		function tiShi(btn){
			//当前进价(输入框)的值 变动过之后
			var val=btn.value;
			//要做的事:需要找到进价录入之前的值  并进行比较
			//定义变量 将本行的id编号赋值给变量
			var trId=btn.parentElement.parentElement.children[0].innerHTML;  
			//遍历数组 与数组中的id编号进行比较
			for(var i=0;i<goods.length;i++){
				//逐个获取数组的值
				var gId=goods[i];
				//与每行的id编号进行比较
				if(gId.goodid==trId){
					if(Number(val)>gId.goodprice){
						confirm("进价太高了,不可用");
						break;
					//刷新小计(只有满足进价小于单价时才会刷新小计)
					}else{
						//定义变量 存储行元素
						var tr=btn.parentElement.parentElement;
						//这里的children[0]是因为tr.children[4]包含 <td><input ...></td>,需要取第一个
						tr.children[5].innerHTML=Number(val)*Number(tr.children[4].children[0].value);
					}
				}
				/*//刷新小计(局限性:不受条件约束。如果函数定义在这里的话,售价高于单价时也将会刷新小计)
				var tr=btn.parentElement.parentElement;
				tr.children[5].innerHTML=Number(val)*Number(tr.children[4].children[0].value);*/
				//刷新总计
				sum();
			}
		}
		
	
		//输入购买数量为非数字或小于1时 提示信息
		function changeNumber(btn){
			//判断输入的购买数量个数 是否为数字
			if(isNaN(btn.value)){
				confirm('录入为非数字');
			//判断输入的购买数量个数 是否<1
			}else if(Number(btn.value)<1){
				confirm('录入数字<1');
			//判断输入的购买数量个数 是否大于库存
			}else{
				//当前购买数量(输入框)的值 变动过之后
				var val=btn.value;
				//要做的事:需要找到原库存的值  并进行比较
				//定义变量 将本行的id编号赋值给变量
				var trId=btn.parentElement.parentElement.children[0].innerHTML;  
				//遍历数组 与数组中的id编号进行比较
				for(var i=0;i<goods.length;i++){
					//逐个获取数组的值
					var gId=goods[i];
					//与每行的id编号进行比较 相同时下一步
					if(gId.goodid==trId){
						//购买数量 库存数量 进行比较 (注意:这里需要和数组作比较 因为数组中的数量是固定不变的)
						if(Number(val)>gId.goodstore){
							//大于时 提示信息
							confirm("达到库存数量的上限,请重新输入");
							break; //当大于库存数量时,跳出判断(小计不需要刷新)
						}
						/* //注意:这步也需要改变库存的值 故需要把这步判断放到下面(或重复代码进行编写)
						else if(Number(val)==gId.goodstore){
							confirm("此时商品已售空,请不要再继续购买");
							//刷新小计 //当等于库存数量时,(小计需要继续要刷新)然后跳出判断
							btn.parentElement.nextElementSibling.innerHTML = Number(btn.value)*Number(btn.parentElement.previousElementSibling.children[0].value);
							break;
						//小于时 库存数量做相应的减少	
						}*/
						else{ //(注意:这里需要改变商品库存信息表单中库存的数量 需要获得表单中的元素对象)
							//gId.goodstore.innerHTML=gId.goodstore.innerHTML-val;(错误思路)
							
							//商品库存信息表单中的结构是固定的 我们只需要通过元素节点获取想要的数据即可 
							//与商品行id作比较 找到相应的行 然后操作其库存数量
							//遍历表单 条件是小于数组长度(不变) 操作是对表单进行操作(表单长度跟随数组) 
							for(var i=0;i<goods.length;i++){ 
								//定义变量 存储表单对应的行元素
								var trH=fbody.children[i];
								//id进行比较 找到相应的行 对库存进行比较
								if(trH.children[0].innerHTML==trId){
									//表单中库存数量做相应改变
									trH.children[4].innerHTML=gId.goodstore-Number(val);
									//当售空时 提示
									if(Number(val)==gId.goodstore){
										confirm("此时商品已售空,请不要再继续购买");
									}
									//刷新小计 
									btn.parentElement.nextElementSibling.innerHTML = Number(btn.value)*Number(btn.parentElement.previousElementSibling.children[0].value);
								}
							}
						}
					}
				}
				/*//刷新小计 (新的条件添加后,需要调整刷新小计的位置)
				btn.parentElement.nextElementSibling.innerHTML = Number(btn.value)*Number(btn.parentElement.previousElementSibling.children[0].value);*/
				
			}
			/*//刷新小计(局限性:不受条件约束。不满足条件时,也会刷新小计)
			btn.parentElement.nextElementSibling.innerHTML = Number(btn.value)*Number(btn.parentElement.previousElementSibling.children[0].value);
				//<td><input ...></td>  children[0] 【这里可以看出/*注释优先级比//大,且第一个/*遇到*(转义字符)\/才会结束】*/ 
			//刷新总计
			sum();	
		}

		//以上函数定义总结:条件逐步进行缩减排除,便判断便操作

		/*//输入购买数量为非数字或小于1时 提示信息
		function changeNumber(btn){
			//判断输入的购买数量个数 是否为数字
			if(isNaN(btn.value)){
				confirm('录入为非数字');
			//判断输入的购买数量个数 是否<1
			}else if(Number(btn.value)<1){
				confirm('录入数字<1');
			//判断输入的购买数量个数 是否大于库存
			}else{
				//当前购买数量(输入框)的值 变动过之后
				var val=btn.value;
				//要做的事:需要找到原库存的值  并进行比较
				//定义变量 将本行的id编号赋值给变量
				var trId=btn.parentElement.parentElement.children[0].innerHTML;  
				//遍历数组 与数组中的id编号进行比较
				for(var i=0;i<goods.length;i++){
					//逐个获取数组的值
					var gId=goods[i];
					//与每行的id编号进行比较 相同时下一步
					if(gId.goodid==trId){
						//购买数量 库存数量 进行比较
						if(Number(val)>gId.goodstore){
							//大于时 提示信息
							confirm("库存数量已达上限,请重新输入");
						//小于时 库存数量做相应的减少	
						}
					}
				}
	
			}
			//刷新小计
			btn.parentElement.nextElementSibling.innerHTML = Number(btn.value)*Number(btn.parentElement.previousElementSibling.children[0].value);//<td><input ...></td>  children[0] 同上
			 
			//刷新总计
			sum();	
		}*/

		
		//总计
		function sum(){
				// 获取mybody中所有的tr行
				var mytr = mybody.children;
				
				var zongji = 0;
				// 遍历tr行 对行内数据进行计算
				for(var i=0;i<mytr.length;i++){
					// 逐个取出当前遍历到的数组中的tr元素
					var tr = mytr[i];
					// 通过tr,获取tr中下标为5的小计单元格,取出数据
					var xj = Number(tr.children[5].innerText);
					// 累加小计到zongji变量
					zongji+=xj;
				}
				// 计算汇总
				total.innerText = zongji;
			}
		
		//基本功能模块:(已完成)
					 //json数组已给出!通过json数组实现一下功能:

					 //实现购物车的添加:
					 //每次点击商品行添加按钮时:
						//1.采购详情表单已存在该行,数量实现自动加一
						//2.采购详情表单不存在该行,创建商品行

					 //实现购物车的删除:
					 //当点击采购详情表单行中的删除按钮时,弹出“确定要删除吗”提示
						//1.“确定” 删除
						//2.“取消” 不删除
					 
					 //计算总结:
						//每次添加商品之后,商品总计都要进行更新。

		//待完善的功能模块:(已完成)
					 //判断进价:
						//如果超过单价,则提示信息 不进行操作 (以上已完成)
					 
					 //判断输入数量:
					 //1.输入框输入时:
					 //购买数量不能超过库存数量 否则会弹出提示信息 (以上已完成)
					 //每次购买数量加一,库存数量减一 (以上已完成)
					 //库存数量减少到0,提示库存信息为空,无法再购买。 (以上已完成)
					 //2.点击添加按钮增加数量时:
					 //当点击添加时,每进行一次增加,库存数量都做相应的减少 
					 //当库存为空时,点击商品库存信息表单添加的按钮时:
						//1:提示信息
						//2:再次点击添加按钮时,采购详情表单行不执行任何操作

		//其他的功能模块:(非必要,待完成)
					 //输入框实现“+”“-”按钮功能 
					 //每次点击 输入框数量变化 小计变化 总计变化。。。。。等等吧
					 

		//总结:项目时 边运行程序边编写代码 边注释 修改代码前记得先备份再修改,防止出错
			//元素节点掌握的不是太牢固;需要多独立思考;多总结复杂易迷问题的思路
			//节点元素掌握的不是太牢固 之前的时候要多复习 好家伙 隔了一个月都给忘了
			//break 方法/函数结束 break 循环/判断结束 
			//continue 跳过break后的循环,返回循环的头部继续进行循环 【循环:for循环或swith-case循环等】
	
	</script>
		
	</body>
</html>

3.运行结果模块

添加功能效果图:

请添加图片描述

删除功能效果图:

请添加图片描述

操作购买数量输入框效果图:

请添加图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

操作进价输入框效果图:

请添加图片描述

在这里插入图片描述

操作添加按钮效果图:

请添加图片描述

在这里插入图片描述
在这里插入图片描述

4.分析总结模块

//总结:项目时 边运行程序边编写代码 边注释 修改代码前记得先备份再修改,防止出错
		//元素节点掌握的不是太牢固;需要多独立思考;多总结复杂易迷问题的思路
		//节点元素掌握的不是太牢固 之前的时候要多复习 好家伙 隔了一个月都给忘了
		//break 方法/函数结束 break 循环/判断结束 
		//continue 跳过break后的循环,返回循环的头部继续进行循环 【循环:for循环或swith-case循环等】

欢迎在评论区留言评论哦~

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值