Javascript實(shí)現(xiàn)購物車功能的詳細(xì)代碼
我們肯定都很熟悉商品購物車這一功能,每當(dāng)我們?cè)谀硨毮硸|上購買商品的時(shí)候,看中了哪件商品,就會(huì)加入購物車中,最后結(jié)算。購物車這一功能,方便消費(fèi)者對(duì)商品進(jìn)行管理,可以添加商品,刪除商品,選中購物車中的某一項(xiàng)或幾項(xiàng)商品,最后商品總價(jià)也會(huì)隨著消費(fèi)者的操作隨著變化。
現(xiàn)在,筆者對(duì)購物車進(jìn)行了簡(jiǎn)單實(shí)現(xiàn),能夠?qū)崿F(xiàn)真實(shí)購物車當(dāng)中的大部分功能。在本示例當(dāng)中,用到了javascript中BOM操作,DOM操作,表格操作,cookie,json等知識(shí)點(diǎn),同時(shí),采用三層架構(gòu)方式對(duì)購物車進(jìn)行設(shè)計(jì),對(duì)javascript的綜合應(yīng)用較強(qiáng),對(duì)javascript初學(xué)者進(jìn)階有一定的益處。
請(qǐng)看主頁效果圖:
現(xiàn)在讀者已經(jīng)對(duì)主頁的效果圖進(jìn)行了了解,我在這里附上主頁的html代碼,供讀者參考,建議讀者根據(jù)自己的思路寫代碼。
請(qǐng)看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> <div class="container"> <h1>商品列表</h1> <div class="mycar"> <a href="cart.html" rel="external nofollow" >我的購物車</a><i id="ccount">0</i> </div> <div 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>智能手機(jī)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>華為手機(jī)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>華為手機(jī)003</dd> <dd>杠杠的</dd> <dd>¥<span>2000</span></dd> <dd> <button>添加購物車</button> </dd> </dl> </div> </div> <!-- 描述:數(shù)據(jù)訪問層,操作本地?cái)?shù)據(jù)的模塊 --> <script type="text/javascript" src="../js/server.js"></script> <!-- 描述:本頁面的js操作 --> <script type="text/javascript" src="../js/index.js"></script> </body> </html>
html結(jié)構(gòu)代碼有了之后,就可以對(duì)主頁進(jìn)行css表現(xiàn)設(shè)計(jì),這里不對(duì)css進(jìn)行過多講解。
我們對(duì)主頁進(jìn)行設(shè)計(jì)之后,就可以進(jìn)行與主頁相關(guān)的DOM操作,涉及到添加按鈕的點(diǎn)擊事件,cookie和json的應(yīng)用,cookie主要為了讓當(dāng)前數(shù)據(jù)與購物車進(jìn)行共享,以方便操作。請(qǐng)看與之相關(guān)的javascript代碼:
這是index.js代碼,主要是主頁的相關(guān)操作:
/* 思路: 第一步:獲取所要操作的節(jié)點(diǎn)對(duì)象 第二步:當(dāng)頁面加載完后,需要計(jì)算本地cookie存了多少【個(gè)】商品,把個(gè)數(shù)賦值給ccount 第三步:為每一個(gè)商品對(duì)應(yīng)的添加購物車按鈕綁定一個(gè)點(diǎn)擊事件onclick 更改本地的cookie 獲取當(dāng)前商品的pid 循環(huán)遍歷本地的cookie轉(zhuǎn)換后的數(shù)組,取出每一個(gè)對(duì)象的pid進(jìn)行對(duì)比,若相等則該商品不是第一次添加 從購物車中取出該商品,然后更pCount值追加1 否則:創(chuàng)建一個(gè)新的對(duì)象,保存到購物中。同時(shí)該商品的數(shù)量為1 */ var ccount = document.getElementById("ccount"); //顯示商品總數(shù)量的標(biāo)簽節(jié)點(diǎn)對(duì)象 var btns = document.querySelectorAll(".list dl dd button"); //所有的購物車按鈕 //約定好用名稱為datas的cookie來存放購物車?yán)锏臄?shù)據(jù)信息 datas里所存放的就是一個(gè)json字符串 var listStr = cookieObj.get("datas"); /*判斷一下本地是否有一個(gè)購物車(datas),沒有的話,創(chuàng)建一個(gè)空的購物車,有的話就直接拿來使用*/ if(!listStr) { //沒有購物車 datas json cookieObj.set({ name: "datas", value: "[]" }); listStr = cookieObj.get("datas"); } var listObj = JSON.parse(listStr); //數(shù)組 /*循環(huán)遍歷數(shù)組,獲取每一個(gè)對(duì)象中的pCount值相加總和*/ var totalCount = 0; //默認(rèn)為0 for(var i = 0, len = listObj.length; i < len; i++) { totalCount = listObj[i].pCount + totalCount; } ccount.innerHTML = totalCount; /*循環(huán)為每一個(gè)按鈕添加點(diǎn)擊事件*/ 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;//獲取所有子節(jié)點(diǎn) 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的設(shè)置獲取操作,采用單例設(shè)計(jì)模式進(jìn)行了封裝設(shè)計(jì),請(qǐng)看代碼:
/* 單例設(shè)計(jì)模式 完整形式:[]中是可選項(xiàng) document.cookie = “name=value[;expires=date][;path=path-to-resource][;domain=域名][;secure]” */ var cookieObj = { /* 增加或修改cookie 參數(shù):o 對(duì)象{} name:string cookie名 value:string cookie值 expires:Date對(duì)象 過期時(shí)間 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; }, /* 刪除 參數(shù):n string cookie的名字 */ del: function(n) { var date = new Date(); date.setHours(-1); //this代表的是當(dāng)前函數(shù)的對(duì)象 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代碼,主要對(duì)購物車中各種操作進(jìn)行了封裝,比如商品個(gè)數(shù)統(tǒng)計(jì),更新獲取本地?cái)?shù)據(jù)等操作,方便代碼管理,請(qǐng)看代碼:
/* 功能:查看本地?cái)?shù)據(jù)中是否含有指定的對(duì)象(商品),根據(jù)id 參數(shù):id:商品的標(biāo)識(shí) */ 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; } /* 功能:更新本地?cái)?shù)據(jù) 參數(shù):arr 數(shù)組對(duì)象 返回一個(gè)值:最新的本地轉(zhuǎn)換后的數(shù)組對(duì)象 * */ function updateData(arr) { var jsonStr = JSON.stringify(arr); cookieObj.set({ name: "datas", value: jsonStr }); jsonStr = cookieObj.get("datas"); return JSON.parse(jsonStr); } /* 獲取商品的總數(shù)量 返回:數(shù)字 */ function getTotalCount() { /*循環(huán)遍歷數(shù)組,獲取每一個(gè)對(duì)象中的pCount值相加總和*/ var totalCount = 0; //默認(rèn)為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; } /* 更新本地?cái)?shù)據(jù)根據(jù)pid id:商品的標(biāo)識(shí) */ 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) } /* 獲取本地?cái)?shù)據(jù) 返回 數(shù)組對(duì)象 * */ 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; }
因?yàn)樯鲜龃a中涉及了進(jìn)入購物車后的一些操作,讀者看了之后可能會(huì)感動(dòng)疑惑,不用擔(dān)心,下面請(qǐng)看點(diǎn)擊進(jìn)入我的購物車之后的分析。
請(qǐng)看效果圖:
筆者在主頁中點(diǎn)擊了三種商品,共點(diǎn)擊了七次,在購物車中出現(xiàn)了相應(yīng)商品以及價(jià)格計(jì)算。對(duì)于途中的各種信息,相信讀者一目了然。請(qǐng)看本購物車的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> <div 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> 數(shù)量 </th> <th> 單價(jià) </th> <th> 小計(jì) </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> <div class="box" id="box">購物車?yán)餂]有任何商品</div> <h2 id="h2" class="">總價(jià)格:¥<span id="totalPrice">0</span></h2> </div> <script src="../js/server.js" type="text/javascript" charset="utf-8"></script> <!--操作購物車頁面的cart.js--> <script src="../js/cart.js"></script> </body> </html>
在對(duì)購物車進(jìn)行相關(guān)的表現(xiàn)設(shè)計(jì)之后,既要進(jìn)行javascript行為設(shè)計(jì),請(qǐng)看與本頁相關(guān)的cart.js代碼:
/* 思路: 第一步:當(dāng)頁面加載完后,根據(jù)本地的數(shù)據(jù),動(dòng)態(tài)生成表格(購物車列表) 獲取所要操作的節(jié)點(diǎn)對(duì)象 判斷購物車中是否有數(shù)據(jù)? 有: 顯示出購物列表 沒有: 提示購物車為空 第二步:當(dāng)購物車列表動(dòng)態(tài)生成后,獲取tbody里所有 的checkeBox標(biāo)簽節(jié)點(diǎn)對(duì)象,看那個(gè)被選中就獲取對(duì)應(yīng)行小計(jì)進(jìn)行總價(jià)格運(yùn)算。 第三步: 為每一個(gè)checkbox添加一個(gè)onchange事件,根據(jù)操作更改總價(jià)格 第四步:全選 第五步: 為加減按鈕添加一個(gè)鼠標(biāo)點(diǎn)擊事件 更改該商品的數(shù)量 第六步:刪除 獲取所有的刪除按鈕 為刪除按鈕添加一個(gè)鼠標(biāo)點(diǎn)擊事件 刪除當(dāng)前行,并更新本地?cái)?shù)據(jù) */ 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); } } /* 功能:計(jì)算總價(jià)格 */ 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) { //如果當(dāng)前被選中 var tr = cks[i].parentNode.parentNode; var temp = tr.children[5].firstElementChild.innerHTML; sum = Number(temp) + sum; } } return sum; } /*循環(huán)遍歷為每一個(gè)checkbox添加一個(gè)onchange事件*/ for(var i = 0, len = cks.length; i < len; i++) { cks[i].onchange = function() { checkAllChecked(); totalPrice.innerHTML = getTotalPrice(); } } /*全選實(shí)現(xiàn)*/ 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;//下一個(gè)兄弟節(jié)點(diǎn) 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;//上一個(gè)兄弟節(jié)點(diǎn) 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(); } } /*檢測(cè)是否要全選*/ function checkAllChecked() { var isSelected = true; //全選是否會(huì)選中 for(var j = 0, len = cks.length; j < len; j++) { if(cks[j].checked == false) { isSelected = false; break; } } allCheck.checked = isSelected; }
上述代碼完成了購物車中的相關(guān)操作,比如價(jià)格計(jì)算,商品數(shù)量更換,商品刪除等操作。
到這里我們已經(jīng)完成了購物車的大部分功能,我們對(duì)html,css, BOM,DOM,json,cookie等進(jìn)行了綜合應(yīng)用,相信讀者理解之后一定會(huì)對(duì)自己的javascript學(xué)習(xí)更進(jìn)一步,本示例中涉及的大部分代碼都在本頁中貼出,部分代碼資源未向讀者展示,讀者可以點(diǎn)擊下面的資源鏈接,下載本示例的全部代碼及圖片資料。本示例采用HBuilder編譯器編譯運(yùn)行,涉及cookie操作,請(qǐng)讀者自行安裝服務(wù)器或者添加到HBuilder中運(yùn)行查看。
資源鏈接:購物車全部資源下載
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- vuejs手把手教你寫一個(gè)完整的購物車實(shí)例代碼
- js購物車實(shí)現(xiàn)思路及代碼(個(gè)人感覺不錯(cuò))
- JavaScript編寫一個(gè)簡(jiǎn)易購物車功能
- js實(shí)現(xiàn)簡(jiǎn)單的購物車有圖有代碼
- Jsp+Servlet實(shí)現(xiàn)購物車功能
- 原生js模擬淘寶購物車項(xiàng)目實(shí)戰(zhàn)
- Javascript操縱Cookie實(shí)現(xiàn)購物車程序
- 簡(jiǎn)單的前端js+ajax 購物車框架(入門篇)
- js實(shí)現(xiàn)購物車功能
- JavaScript實(shí)現(xiàn)淘寶購物件數(shù)選擇
相關(guān)文章
JS實(shí)現(xiàn)的哈夫曼編碼示例【原始版與修改版】
這篇文章主要介紹了JS實(shí)現(xiàn)的哈夫曼編碼,結(jié)合實(shí)例形式分析了基于JavaScript定義、使用哈夫曼樹進(jìn)行編碼、解碼等相關(guān)操作技巧,需要的朋友可以參考下2018-04-04js 中將多個(gè)逗號(hào)替換為一個(gè)逗號(hào)的代碼
這篇文章主要介紹了js 中將多個(gè)逗號(hào)替換為一個(gè)逗號(hào)的代碼,需要的朋友可以參考下2014-06-06Jquery把獲取到的input值轉(zhuǎn)換成json
本篇文章主要介紹了Jquery把獲取到的input值轉(zhuǎn)換成json的相關(guān)知識(shí),具有很好的參考價(jià)值。下面跟著小編一起來看下吧2017-05-05javascript判斷元素存在和判斷元素存在于實(shí)時(shí)的dom中的方法
本文主要介紹了javascript判斷元素存在和判斷元素存在于實(shí)時(shí)的dom中的方法。具有一定的參考價(jià)值,下面跟著小編一起來看下吧2017-01-01