這次帶給大家JS實作簡單購物車功能程式碼分析,JS實作簡單購物車功能的注意事項有哪些,以下就是實戰案例,一起來看一下。
我們肯定都很熟悉商品購物車這項功能,每當我們在某寶某東上購買商品的時候,看中了哪件商品,就會加入購物車中,最後結算。購物車這項功能,方便消費者對商品進行管理,可以添加商品,刪除商品,選中購物車中的某一項或幾項商品,最後商品總價也會隨著消費者的操作隨著變化。
現在,筆者對購物車進行了簡單實現,能夠實現真實購物車當中的大部分功能。在這個範例當中,用到了javascript中BOM操作,DOM操作,表格操作,cookie,json等知識點,同時,採用三層架構方式對購物車進行設計,對javascript的綜合應用較強,對javascript初學者進階有一定的益處。
請看主頁效果圖:
現在讀者已經對主頁的效果圖進行了了解,我在這裡附上主頁的html代碼,供讀者參考,建議讀者依照自己的想法寫程式。
請看html程式碼:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>商品列表页面</title> <!--商品列表样式表--> <link rel="stylesheet" type="text/css" href="../css/index.css" rel="external nofollow" /> <!--cookie操作的js库--> <script src="../js/cookie.js" type="text/javascript" charset="utf-8"></script> </head> <body> <p class="container"> <h1>商品列表</h1> <p class="mycar"> <a href="cart.html" rel="external nofollow" >我的购物车</a><i id="ccount">0</i> </p> <p class="list"> <dl pid="1001"> <dt> <img src="../images/p1.jpg" /> </dt> <dd>智能手表</dd> <dd>酷黑,棒,棒,棒,棒</dd> <dd>¥<span>998</span></dd> <dd> <button>添加购物车</button> </dd> </dl> <dl pid="1002"> <dt> <img src="../images/p2.jpg" /> </dt> <dd>智能手机001</dd> <dd>金红色,酷酷酷酷</dd> <dd>¥<span>1998</span></dd> <dd> <button>添加购物车</button> </dd> </dl> <dl pid="1003"> <dt> <img src="../images/p3.jpg" /> </dt> <dd>华为手机002</dd> <dd>帅帅帅帅帅帅帅帅帅帅</dd> <dd>¥<span>998</span></dd> <dd> <button>添加购物车</button> </dd> </dl> <dl pid="1004"> <dt> <img src="../images/p4.jpg" /> </dt> <dd>华为手机003</dd> <dd>杠杠的</dd> <dd>¥<span>2000</span></dd> <dd> <button>添加购物车</button> </dd> </dl> </p> </p> <!-- 描述:数据访问层,操作本地数据的模块 --> <script type="text/javascript" src="../js/server.js"></script> <!-- 描述:本页面的js操作 --> <script type="text/javascript" src="../js/index.js"></script> </body> </html>
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 = 0, len = listObj.length; i < len; i++) { totalCount = listObj[i].pCount + totalCount; } ccount.innerHTML = totalCount; /*循环为每一个按钮添加点击事件*/ for(var i = 0, len = btns.length; i < len; i++) { btns[i].onclick = function() { var dl = this.parentNode.parentNode; var pid = dl.getAttribute("pid");//获取自定义属性 var arrs = dl.children;//获取所有子节点 if(checkObjByPid(pid)) { listObj = updateObjById(pid, 1) } else { var imgSrc = arrs[0].firstElementChild.src; var pName = arrs[1].innerHTML; var pDesc = arrs[2].innerHTML; var price = arrs[3].firstElementChild.innerHTML; var obj = { pid: pid, pImg: imgSrc, pName: pName, pDesc: pDesc, price: price, pCount: 1 }; listObj.push(obj) listObj = updateData(listObj); } ccount.innerHTML = getTotalCount(); } }
這是cookie.js的程式碼,主要涉及cookie的設定獲取操作,採用單例設計模式進行了封裝設計,請看程式碼:
/* 单例设计模式 完整形式:[]中是可选项 document.cookie = “name=value[;expires=date][;path=path-to-resource][;domain=域名][;secure]” */ var cookieObj = { /* 增加或修改cookie 参数:o 对象{} name:string cookie名 value:string cookie值 expires:Date对象 过期时间 path:string 路径限制 domain:string 域名限制 secure:boolean true https false或undeinfed */ set: function(o) { var cookieStr = encodeURIComponent(o.name) + "=" + encodeURIComponent(o.value); if(o.expires) { cookieStr += ";expires=" + o.expires; } if(o.path) { cookieStr += ";path=" + o.path; } if(o.domain) { cookieStr += ";domain=" + o.domain; } if(o.secure) { cookieStr += ";secure"; } document.cookie = cookieStr; }, /* 删除 参数:n string cookie的名字 */ del: function(n) { var date = new Date(); date.setHours(-1); //this代表的是当前函数的对象 this.set({ name: n, expires: date }); }, /*查找*/ get: function(n) { n = encodeURIComponent(n); var cooikeTotal = document.cookie; var cookies = cooikeTotal.split("; "); for(var i = 0, len = cookies.length; i < len; i++) { var arr = cookies[i].split("="); if(n == arr[0]) { return decodeURIComponent(arr[1]); } } } }
下面的是server.js程式碼,主要對購物車中各種操作進行了封裝,例如商品數統計,更新取得本地資料等操作,方便程式碼管理,請看程式碼:
/* 功能:查看本地数据中是否含有指定的对象(商品),根据id 参数:id:商品的标识 */ function checkObjByPid(id) { var jsonStr = cookieObj.get("datas"); var jsonObj = JSON.parse(jsonStr); var isExist = false; for(var i = 0, len = jsonObj.length; i < len; i++) { if(jsonObj[i].pid == id) { isExist = true; break; } } return isExist; //return false; } /* 功能:更新本地数据 参数:arr 数组对象 返回一个值:最新的本地转换后的数组对象 * */ function updateData(arr) { var jsonStr = JSON.stringify(arr); cookieObj.set({ name: "datas", value: jsonStr }); jsonStr = cookieObj.get("datas"); return JSON.parse(jsonStr); } /* 获取商品的总数量 返回:数字 */ function getTotalCount() { /*循环遍历数组,获取每一个对象中的pCount值相加总和*/ var totalCount = 0; //默认为0 var jsonStr = cookieObj.get("datas"); var listObj = JSON.parse(jsonStr); for(var i = 0, len = listObj.length; i < len; i++) { totalCount = listObj[i].pCount + totalCount; } return totalCount; } /* 更新本地数据根据pid id:商品的标识 */ function updateObjById(id, num) { var jsonStr = cookieObj.get("datas"); var listObj = JSON.parse(jsonStr); for(var i = 0, len = listObj.length; i < len; i++) { if(listObj[i].pid == id) { listObj[i].pCount = listObj[i].pCount + num; break; } } return updateData(listObj) } /* 获取本地数据 返回 数组对象 * */ function getAllData() { var jsonStr = cookieObj.get("datas"); var listObj = JSON.parse(jsonStr); return listObj; } function deleteObjByPid(id) { var lisObj = getAllData(); for(var i = 0, len = lisObj.length; i < len; i++) { if(lisObj[i].pid == id) { lisObj.splice(i, 1); break; } } updateData(lisObj); return lisObj; }
因為上述程式碼中涉及了進入購物車後的一些操作,讀者看了之後可能會感動疑惑,不用擔心,下面請看點擊進入我的購物車之後的分析。
請看效果圖:
筆者在首頁點擊了三種商品,共點擊了七次,在購物車中出現了對應商品以及價格計算。對於途中的各種訊息,相信讀者一目了然。請看本購物車的html程式碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>购物车</title> <!--购物车样式表--> <link rel="stylesheet" type="text/css" href="../css/cart.css" rel="external nofollow" /> <!--操作cookie的js文件--> <script type="text/javascript" src="../js/cookie.js"></script> </head> <body> <p class="container"> <h1>购物车</h1> <h3><a href="index.html" rel="external nofollow" >返回商品列表页面</a></h3> <table id="table" border="1" cellspacing="0" cellpadding="0" class="hide"> <thead> <tr> <th> <input type="checkbox" id="allCheck" class="ck" />全选 </th> <th> 图片 </th> <th> 描述 </th> <th> 数量 </th> <th> 单价 </th> <th> 小计 </th> <th> 操作 </th> </tr> </thead> <tbody id="tbody"> <!-- <tr> <td> <input type="checkbox" class="ck" /> </td> <td> <img src="../images/p1.jpg" alt="" /> </td> <td> 酷黑,棒棒棒棒 </td> <td> <button class="down">-</button><input type="text" value="1" readonly="readonly" /><button class="up">+</button> </td> <td> ¥<span>111</span> </td> <td> ¥<span>111</span> </td> <td> <button class="del" >删除</button> </td> </tr> --> </tbody> </table> <p class="box" id="box">购物车里没有任何商品</p> <h2 id="h2" class="">总价格:¥<span id="totalPrice">0</span></h2> </p> <script src="../js/server.js" type="text/javascript" charset="utf-8"></script> <!--操作购物车页面的cart.js--> <script src="../js/cart.js"></script> </body> </html>
在對購物車進行相關的表現設計之後,既要進行javascript行為設計,請看與本頁相關的cart.js程式碼:
/* 思路: 第一步:当页面加载完后,根据本地的数据,动态生成表格(购物车列表) 获取所要操作的节点对象 判断购物车中是否有数据? 有: 显示出购物列表 没有: 提示购物车为空 第二步:当购物车列表动态生成后,获取tbody里所有 的checkeBox标签节点对象,看那个被选中就获取对应行小计进行总价格运算。 第三步: 为每一个checkbox添加一个onchange事件,根据操作更改总价格 第四步:全选 第五步: 为加减按钮添加一个鼠标点击事件 更改该商品的数量 第六步:删除 获取所有的删除按钮 为删除按钮添加一个鼠标点击事件 删除当前行,并更新本地数据 */ var listObj = getAllData(); var table = document.getElementById("table") var box = document.getElementById("box") var tbody = document.getElementById("tbody"); var totalPrice = document.getElementById("totalPrice"); var allCheck = document.getElementById("allCheck"); if(listObj.length == 0) { //购物车为空 box.className = "box"; table.className = "hide"; } else { box.className = "box hide"; table.className = ""; for(var i = 0, len = listObj.length; i < len; i++) { var tr = document.createElement("tr"); tr.setAttribute("pid", listObj[i].pid); //{"pid":值,"pImg":值,"pName":值,"pDesc":值,"price":值,"pCount":1}, tr.innerHTML = '<td>' + '<input type="checkbox" class="ck" />' + '</td>' + '<td>' + '<img src="' + listObj[i].pImg + '" alt="" />' + '</td>' + '<td>' + listObj[i].pDesc + '</td>' + '<td>' + '<button class="down">-</button><input type="text" value="' + listObj[i].pCount + '" readonly="readonly" /><button class="up">+</button>' + '</td>' + '<td>' + '¥<span>' + listObj[i].price + '</span>' + '</td>' + '<td>' + '¥<span>' + listObj[i].price * listObj[i].pCount + '</span>' + '</td>' + '<td>' + '<button class="del" >删除</button>' + '</td>'; tbody.appendChild(tr); } } /* 功能:计算总价格 */ var cks = document.querySelectorAll("tbody .ck"); function getTotalPrice() { cks = document.querySelectorAll("tbody .ck"); var sum = 0; for(var i = 0, len = cks.length; i < len; i++) { if(cks[i].checked) { //如果当前被选中 var tr = cks[i].parentNode.parentNode; var temp = tr.children[5].firstElementChild.innerHTML; sum = Number(temp) + sum; } } return sum; } /*循环遍历为每一个checkbox添加一个onchange事件*/ for(var i = 0, len = cks.length; i < len; i++) { cks[i].onchange = function() { checkAllChecked(); totalPrice.innerHTML = getTotalPrice(); } } /*全选实现*/ allCheck.onchange = function() { if(this.checked) { for(var i = 0, len = cks.length; i < len; i++) { cks[i].checked = true; } } else { for(var i = 0, len = cks.length; i < len; i++) { cks[i].checked = false; } } totalPrice.innerHTML = getTotalPrice(); } var downs = document.querySelectorAll(".down"); //一组减的按钮 var ups = document.querySelectorAll(".up"); //一组加的按钮 var dels = document.querySelectorAll(".del"); //一组删除按钮 for(var i = 0, len = downs.length; i < len; i++) { downs[i].onclick = function() { var txtObj = this.nextElementSibling;//下一个兄弟节点 var tr = this.parentNode.parentNode; var pid = tr.getAttribute("pid"); txtObj.value = txtObj.value - 1; if(txtObj.value < 1) { txtObj.value = 1; updateObjById(pid, 0) } else { updateObjById(pid, -1) } tr.children[0].firstElementChild.checked = true; checkAllChecked(); var price = tr.children[4].firstElementChild.innerHTML; tr.children[5].firstElementChild.innerHTML = price * txtObj.value; totalPrice.innerHTML = getTotalPrice(); } ups[i].onclick = function() { var txtObj = this.previousElementSibling;//上一个兄弟节点 var tr = this.parentNode.parentNode; var pid = tr.getAttribute("pid"); txtObj.value = Number(txtObj.value) + 1; updateObjById(pid, 1) tr.children[0].firstElementChild.checked = true; checkAllChecked() var price = tr.children[4].firstElementChild.innerHTML; tr.children[5].firstElementChild.innerHTML = price * txtObj.value; totalPrice.innerHTML = getTotalPrice(); } dels[i].onclick = function() { var tr = this.parentNode.parentNode; var pid = tr.getAttribute("pid") if(confirm("确定删除?")) { //remove() 自杀 tr.remove(); listObj = deleteObjByPid(pid); } if(listObj.length == 0) { //购物车为空 box.className = "box"; table.className = "hide"; } else { box.className = "box hide"; table.className = ""; } totalPrice.innerHTML = getTotalPrice(); } } /*检测是否要全选*/ function checkAllChecked() { var isSelected = true; //全选是否会选中 for(var j = 0, len = cks.length; j < len; j++) { if(cks[j].checked == false) { isSelected = false; break; } } allCheck.checked = isSelected; }
上述程式碼完成了購物車中的相關操作,例如價格計算,商品數量更換,商品刪除等操作。
到這裡我們已經完成了購物車的大部分功能,我們對html,css, BOM,DOM,json,cookie等進行了綜合應用,相信讀者理解之後一定會對自己的javascript學習更進一步,本範例中涉及的大部分程式碼都在本頁中貼出,部分程式碼資源未向讀者展示,讀者可以點擊下面的資源鏈接,下載本範例的全部程式碼及圖片資料。本範例採用HBuilder編譯器編譯運行,涉及cookie操作,請讀者自行安裝伺服器或新增至HBuilder中執行檢視。
相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!
推薦閱讀:
以上是JS實現簡單購物車功能代碼分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!