我們肯定都很熟悉商品購物車這一功能,每當我們在某寶某東上購買商品的時候,看中了哪件商品,就會加入購物車中,最后結算。購物車這一功能,方便消費者對商品進行管理,可以添加商品,刪除商品,選中購物車中的某一項或幾項商品,最后商品總價也會隨著消費者的操作隨著變化。
現在,筆者對購物車進行了簡單實現,能夠實現真實購物車當中的大部分功能。在本示例當中,用到了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> <div class="container"> <h2>商品列表</h2> <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>智能手機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> </div> </div> <!-- 描述:數據訪問層,操作本地數據的模塊 --> <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>
<div class="container">
<h2>購物車</h2>
<h4><a href="index.html" rel="external nofollow" >返回商品列表頁面</a></h4>
<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>
<div class="box" id="box">購物車里沒有任何商品</div>
<h3 id="h3" class="">總價格:¥<span id="totalPrice">0</span></h3>
</div>
<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中運行查看。
資源鏈接:購物車全部資源下載
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。