我们肯定都很熟悉商品购物车这一功能,每当我们在某宝某东上购买商品的时候,看中了哪件商品,就会加入购物车中,最后结算。购物车这一功能,方便消费者对商品进行管理,可以添加商品,删除商品,选中购物车中的某一项或几项商品,最后商品总价也会随着消费者的操作随着变化。
现在,笔者对购物车进行了简单实现,能够实现真实购物车当中的大部分功能。在本示例当中,用到了Javascript中BOM操作,DOM操作,表格操作,COOKIE,json等知识点,同时,采用三层架构方式对购物车进行设计,对Javascript的综合应用较强,对Javascript初学者进阶有一定的益处。
请看主页效果图:
现在读者已经对主页的效果图进行了了解,我在这里附上主页的html代码,供读者参考,建议读者根据自己的思路写代码。
请看html代码:
商品列表页面我的购物车0
智能手表酷黑,棒,棒,棒,棒¥998
添加购物车
智能手机001金红色,酷酷酷酷¥1998
添加购物车
华为手机002帅帅帅帅帅帅帅帅帅帅¥998
添加购物车
华为手机003杠杠的¥2000
添加购物车
html结构代码有了之后,就可以对主页进行css表现设计,这里不对css进行过多讲解。
我们对主页进行设计之后,就可以进行与主页相关的DOM操作,涉及到添加按钮的点击事件,COOKIE和json的应用,COOKIE主要为了让当前数据与购物车进行共享,以方便操作。请看与之相关的Javascript代码:
这是index.js代码,主要是主页的相关操作:
/*
思路:
第一步:获取所要操作的节点对象
第二步:当页面加载完后,需要计算本地COOKIE存了多少【个】商品,把个数赋值给ccount
第三步:为每一个商品对应的添加购物车按钮绑定一个点击事件onclick
更改本地的COOKIE
获取当前商品的pid
循环遍历本地的COOKIE转换后的数组,取出每一个对象的pid进行对比,若相等则该商品不是第一次添加
从购物车中取出该商品,然后更pCount值追加1
否则:创建一个新的对象,保存到购物中。同时该商品的数量为1
*/
var ccount = document.getElementById("ccount"); //显示商品总数量的标签节点对象
var btns = document.querySelectorAll(".list dl dd button"); //所有的购物车按钮
//约定好用名称为datas的COOKIE来存放购物车里的数据信息 datas里所存放的就是一个json字符串
var listStr = COOKIEObj.get("datas");
/*判断一下本地是否有一个购物车(datas),没有的话,创建一个空的购物车,有的话就直接拿来使用*/
if(!listStr) { //没有购物车 datas json
COOKIEObj.set({
name: "datas",
value: "[]"
});
listStr = COOKIEObj.get("datas");
}
var listObj = JSON.parse(listStr); //数组
/*循环遍历数组,获取每一个对象中的pCount值相加总和*/
var totalCount = 0; //默认为0
for(var i &#61; 0, len &#61; listObj.length; i totalCount &#61; listObj[i].pCount &#43; totalCount; } ccount.innerHTML &#61; totalCount; /*循环为每一个按钮添加点击事件*/ for(var i &#61; 0, len &#61; btns.length; i btns[i].onclick &#61; function() { var dl &#61; this.parentNode.parentNode; var pid &#61; dl.getAttribute("pid");//获取自定义属性 var arrs &#61; dl.children;//获取所有子节点 if(checkObjByPid(pid)) { listObj &#61; updateObjById(pid, 1) } else { var imgSrc &#61; arrs[0].firstElementChild.src; var pName &#61; arrs[1].innerHTML; var pDesc &#61; arrs[2].innerHTML; var price &#61; arrs[3].firstElementChild.innerHTML; var obj &#61; { pid: pid, pImg: imgSrc, pName: pName, pDesc: pDesc, price: price, pCount: 1 }; listObj.push(obj) listObj &#61; updateData(listObj); } ccount.innerHTML &#61; getTotalCount(); } } 这是COOKIE.js的代码&#xff0c;主要涉及COOKIE的设置获取操作&#xff0c;采用单例设计模式进行了封装设计&#xff0c;请看代码&#xff1a; /* 单例设计模式 完整形式&#xff1a;[]中是可选项 document.COOKIE &#61; “name&#61;value[;expires&#61;date][;path&#61;path-to-resource][;domain&#61;域名][;secure]” */ var COOKIEObj &#61; { /* 增加或修改COOKIE 参数&#xff1a;o 对象{} name:string COOKIE名 value:string COOKIE值 expires:Date对象 过期时间 path:string 路径限制 domain:string 域名限制 secure:boolean true https false或undeinfed */ set: function(o) { var COOKIEStr &#61; encodeURIComponent(o.name) &#43; "&#61;" &#43; encodeURIComponent(o.value); if(o.expires) { COOKIEStr &#43;&#61; ";expires&#61;" &#43; o.expires; } if(o.path) { COOKIEStr &#43;&#61; ";path&#61;" &#43; o.path; } if(o.domain) { COOKIEStr &#43;&#61; ";domain&#61;" &#43; o.domain; } if(o.secure) { COOKIEStr &#43;&#61; ";secure"; } document.COOKIE &#61; COOKIEStr; }, /* 删除 参数&#xff1a;n string COOKIE的名字 */ del: function(n) { var date &#61; new Date(); date.setHours(-1); //this代表的是当前函数的对象 this.set({ name: n, expires: date }); }, /*查找*/ get: function(n) { n &#61; encodeURIComponent(n); var cooikeTotal &#61; document.COOKIE; var COOKIEs &#61; cooikeTotal.split("; "); for(var i &#61; 0, len &#61; COOKIEs.length; i var arr &#61; COOKIEs[i].split("&#61;"); if(n &#61;&#61; arr[0]) { return decodeURIComponent(arr[1]); } } } } 下面的是server.js代码&#xff0c;主要对购物车中各种操作进行了封装&#xff0c;比如商品个数统计&#xff0c;更新获取本地数据等操作&#xff0c;方便代码管理&#xff0c;请看代码&#xff1a; /* 功能&#xff1a;查看本地数据中是否含有指定的对象(商品)&#xff0c;根据id 参数&#xff1a;id&#xff1a;商品的标识 */ function checkObjByPid(id) { var jsonStr &#61; COOKIEObj.get("datas"); var jsonObj &#61; JSON.parse(jsonStr); var isExist &#61; false; for(var i &#61; 0, len &#61; jsonObj.length; i if(jsonObj[i].pid &#61;&#61; id) { isExist &#61; true; break; } } return isExist; //return false; } /* 功能&#xff1a;更新本地数据 参数&#xff1a;arr 数组对象 返回一个值&#xff1a;最新的本地转换后的数组对象 * */ function updateData(arr) { var jsonStr &#61; JSON.stringify(arr); COOKIEObj.set({ name: "datas", value: jsonStr }); jsonStr &#61; COOKIEObj.get("datas"); return JSON.parse(jsonStr); } /* 获取商品的总数量 返回&#xff1a;数字 */ function getTotalCount() { /*循环遍历数组&#xff0c;获取每一个对象中的pCount值相加总和*/ var totalCount &#61; 0; //默认为0 var jsonStr &#61; COOKIEObj.get("datas"); var listObj &#61; JSON.parse(jsonStr); for(var i &#61; 0, len &#61; listObj.length; i totalCount &#61; listObj[i].pCount &#43; totalCount; } return totalCount; } /* 更新本地数据根据pid id:商品的标识 */ function updateObjById(id, num) { var jsonStr &#61; COOKIEObj.get("datas"); var listObj &#61; JSON.parse(jsonStr); for(var i &#61; 0, len &#61; listObj.length; i if(listObj[i].pid &#61;&#61; id) { listObj[i].pCount &#61; listObj[i].pCount &#43; num; break; } } return updateData(listObj) } /* 获取本地数据 返回 数组对象 * */ function getAllData() { var jsonStr &#61; COOKIEObj.get("datas"); var listObj &#61; JSON.parse(jsonStr); return listObj; } function deleteObjByPid(id) { var lisObj &#61; getAllData(); for(var i &#61; 0, len &#61; lisObj.length; i if(lisObj[i].pid &#61;&#61; id) { lisObj.splice(i, 1); break; } } updateData(lisObj); return lisObj; } 因为上述代码中涉及了进入购物车后的一些操作&#xff0c;读者看了之后可能会感动疑惑&#xff0c;不用担心&#xff0c;下面请看点击进入我的购物车之后的分析。 请看效果图&#xff1a; 笔者在主页中点击了三种商品&#xff0c;共点击了七次&#xff0c;在购物车中出现了相应商品以及价格计算。对于途中的各种信息&#xff0c;相信读者一目了然。请看本购物车的html代码&#xff1a; 全选 图片 描述 数量 单价 小计 操作 在对购物车进行相关的表现设计之后&#xff0c;既要进行Javascript行为设计&#xff0c;请看与本页相关的cart.js代码&#xff1a; /* 思路&#xff1a; 第一步&#xff1a;当页面加载完后&#xff0c;根据本地的数据&#xff0c;动态生成表格(购物车列表) 获取所要操作的节点对象 判断购物车中是否有数据&#xff1f; 有&#xff1a; 显示出购物列表 没有&#xff1a; 提示购物车为空 第二步&#xff1a;当购物车列表动态生成后&#xff0c;获取tbody里所有 的checkeBox标签节点对象&#xff0c;看那个被选中就获取对应行小计进行总价格运算。 第三步&#xff1a; 为每一个checkbox添加一个onchange事件&#xff0c;根据操作更改总价格 第四步&#xff1a;全选 第五步&#xff1a; 为加减按钮添加一个鼠标点击事件 更改该商品的数量 第六步&#xff1a;删除 获取所有的删除按钮 为删除按钮添加一个鼠标点击事件 删除当前行&#xff0c;并更新本地数据 */ var listObj &#61; getAllData(); var table &#61; document.getElementById("table") var box &#61; document.getElementById("box") var tbody &#61; document.getElementById("tbody"); var totalPrice &#61; document.getElementById("totalPrice"); var allCheck &#61; document.getElementById("allCheck"); if(listObj.length &#61;&#61; 0) { //购物车为空 box.className &#61; "box"; table.className &#61; "hide"; } else { box.className &#61; "box hide"; table.className &#61; ""; for(var i &#61; 0, len &#61; listObj.length; i var tr &#61; document.createElement("tr"); tr.setAttribute("pid", listObj[i].pid); //{"pid":值,"pImg":值,"pName":值,"pDesc":值,"price":值,"pCount":1}, tr.innerHTML &#61; &#39; &#39;&#39; &#43; &#39; &#39; &#39;&#39; &#43; &#39; &#39; listObj[i].pDesc &#43; &#39; &#39; &#39;-&#43;&#39; &#43; &#39; &#39; &#39;&#xffe5;&#39; &#43; listObj[i].price &#43; &#39;&#39; &#43; &#39; &#39; &#39;&#xffe5;&#39; &#43; listObj[i].price * listObj[i].pCount &#43; &#39;&#39; &#43; &#39; &#39; &#39;删除&#39; &#43; &#39; tbody.appendChild(tr); } } /* 功能&#xff1a;计算总价格 */ var cks &#61; document.querySelectorAll("tbody .ck"); function getTotalPrice() { cks &#61; document.querySelectorAll("tbody .ck"); var sum &#61; 0; for(var i &#61; 0, len &#61; cks.length; i if(cks[i].checked) { //如果当前被选中 var tr &#61; cks[i].parentNode.parentNode; var temp &#61; tr.children[5].firstElementChild.innerHTML; sum &#61; Number(temp) &#43; sum; } } return sum; } /*循环遍历为每一个checkbox添加一个onchange事件*/ for(var i &#61; 0, len &#61; cks.length; i cks[i].onchange &#61; function() { checkAllChecked(); totalPrice.innerHTML &#61; getTotalPrice(); } } /*全选实现*/ allCheck.onchange &#61; function() { if(this.checked) { for(var i &#61; 0, len &#61; cks.length; i cks[i].checked &#61; true; } } else { for(var i &#61; 0, len &#61; cks.length; i cks[i].checked &#61; false; } } totalPrice.innerHTML &#61; getTotalPrice(); } var downs &#61; document.querySelectorAll(".down"); //一组减的按钮 var ups &#61; document.querySelectorAll(".up"); //一组加的按钮 var dels &#61; document.querySelectorAll(".del"); //一组删除按钮 for(var i &#61; 0, len &#61; downs.length; i downs[i].onclick &#61; function() { var txtObj &#61; this.nextElementSibling;//下一个兄弟节点 var tr &#61; this.parentNode.parentNode; var pid &#61; tr.getAttribute("pid"); txtObj.value &#61; txtObj.value - 1; if(txtObj.value <1) { txtObj.value &#61; 1; updateObjById(pid, 0) } else { updateObjById(pid, -1) } tr.children[0].firstElementChild.checked &#61; true; checkAllChecked(); var price &#61; tr.children[4].firstElementChild.innerHTML; tr.children[5].firstElementChild.innerHTML &#61; price * txtObj.value; totalPrice.innerHTML &#61; getTotalPrice(); } ups[i].onclick &#61; function() { var txtObj &#61; this.previousElementSibling;//上一个兄弟节点 var tr &#61; this.parentNode.parentNode; var pid &#61; tr.getAttribute("pid"); txtObj.value &#61; Number(txtObj.value) &#43; 1; updateObjById(pid, 1) tr.children[0].firstElementChild.checked &#61; true; checkAllChecked() var price &#61; tr.children[4].firstElementChild.innerHTML; tr.children[5].firstElementChild.innerHTML &#61; price * txtObj.value; totalPrice.innerHTML &#61; getTotalPrice(); } dels[i].onclick &#61; function() { var tr &#61; this.parentNode.parentNode; var pid &#61; tr.getAttribute("pid") if(confirm("确定删除&#xff1f;")) { //remove() 自杀 tr.remove(); listObj &#61; deleteObjByPid(pid); } if(listObj.length &#61;&#61; 0) { //购物车为空 box.className &#61; "box"; table.className &#61; "hide"; } else { box.className &#61; "box hide"; table.className &#61; ""; } totalPrice.innerHTML &#61; getTotalPrice(); } } /*检测是否要全选*/ function checkAllChecked() { var isSelected &#61; true; //全选是否会选中 for(var j &#61; 0, len &#61; cks.length; j if(cks[j].checked &#61;&#61; false) { isSelected &#61; false; break; } } allCheck.checked &#61; isSelected; } 上述代码完成了购物车中的相关操作&#xff0c;比如价格计算&#xff0c;商品数量更换&#xff0c;商品删除等操作。 到这里我们已经完成了购物车的大部分功能&#xff0c;我们对html&#xff0c;css, BOM,DOM,json,COOKIE等进行了综合应用&#xff0c;相信读者理解之后一定会对自己的Javascript学习更进一步&#xff0c;本示例中涉及的大部分代码都在本页中贴出&#xff0c;部分代码资源未向读者展示&#xff0c;读者可以点击下面的资源链接&#xff0c;下载本示例的全部代码及图片资料。本示例采用HBuilder编译器编译运行&#xff0c;涉及COOKIE操作&#xff0c;请读者自行安装服务器或者添加到HBuilder中运行查看。 以上就是本文的全部内容&#xff0c;希望对大家的学习有所帮助&#xff0c;也希望大家多多支持脚本之家。购物车
返回商品列表页面
总价格&#xff1a;&#xffe5;0