這個案例拖延了三天,今天終於給補上了。
購物車結算的功能,主要就是更新商品的數據了。主要利用的知識是jQuery中元素的獲取、獲取元素的子元素或父元素、操作元素屬性和元素的文本內容以及對jQuery選擇器的應用,等等吧。反正就是把JavaScript裏的操作在這裏更好的用jQuery實現。
這個案例的核心價值我認爲就是數據的獲取與轉換,以及遍歷元素。練習的價值還是挺高的,還有就是更讓我們清除的認識到結構的作用。
廢話不多說,先看下我們需要實現的幾個功能吧。
如圖所示,五個部分。
1. 全選按鈕 和 商品對應的按鈕。
這個部分有兩個部分,首先是全選按鈕選中時下面所有的商品按鈕會選中;其次就是商品部分的按鈕全選中時全選按鈕被選中,有一個商品按鈕沒有選中時全選按鈕就不選中。
這裏註冊事件是用change事件,表示表單發生變化,簡單來說就是表單checked屬性發生變化。代碼裏面的註釋很詳細了,可以看看哈。
// 1.實現全選按鈕控制小按鈕
// 1.1 小按鈕的狀態與全選按鈕的狀態保持一致 prop()固有屬性檢測表單是否被選中
$(".checkall").change(function () {
$(".j-checkbox, .checkall").prop("checked", $(this).prop("checked"));
// 改變背景色
if ($(this).prop("checked")) {
// 添加類 改變背景色
$(this).parents(".cart-item").addClass("check-cart-item");
} else {
// 移除類
$(this).parents(".cart-item").toggleClass("check-cart-item");
}
getSum();
})
// 1.2 小按鈕的狀態決定全選按鈕狀態
$(".j-checkbox").change(function () {
// if(按鈕選中的個數 === 按鈕的總個數){
// 全選選中
// }else{
// 不選擇全選
// }
if ($(".j-checkbox:checked").length === $(".j-checkbox").length) {
$(".checkall").prop("checked", true);
} else {
$(".checkall").prop("checked", false);
}
// 選中時,背景色改變
// ele.parents("指定父級元素")
if ($(this).prop("checked")) {
$(this).parents(".cart-item").addClass("check-cart-item");
} else {
$(this).parents(".cart-item").toggleClass("check-cart-item");
}
// 重新計算小計部分
getSum();
})
2. 點擊+ - 按鈕,實現商品數量的變化;3. 按鈕-/+改變商品數量,同時更新商品總價
這裏就是註冊點擊事件,核心就是確定的是當前點擊的按鈕對應的表單的值變化。通過當前點擊的元素找到對應的表單,獲取表單的值是使用val()方法,普通元素的內容是text()和html()。+按鈕的實現過程與-相似,+有詳細的過程。-按鈕需要做一個判斷,商品數不能小於0.
這裏我們這更新總價放一塊了,以爲點擊-/+按鈕時,右邊的小計部分就要實時變化。
// 2.點擊+ -按鈕來增加和減少商品數量
// 2.1 +添加數量
$(".increment").click(function () {
// 獲取當前 + 的兄弟表單的值
var n = $(this).siblings(".itxt").val();
// 然後點擊一次自增——商品數量
n++;
// console.log(n);
// 數量:表單的商品數量
$(this).siblings(".itxt").val(n);
// 當前被點擊的 + 區域對應的單價
var p = $(this).parents(".p-num").siblings(".p-price").text();
// 返回的是字符串 所以要把¥截取掉 使用substr()截取
// 截取後還是字符串,用parseFloat轉換爲數值型
p = parseFloat(p.substr(1));
console.log(p);
// 獲取當前的總價
var price = $(this).parents(".p-num").siblings(".p-sum").text();
// 去掉¥符號
price = parseFloat(price.substr(1));
// 保留兩位小數點 toFixed(2)
price = (p * n).toFixed(2);
console.log(price);
// 把計算好的商品總和價放到標籤裏
$(this).parents(".p-num").siblings(".p-sum").text("¥" + price);
// 重新計算小結部分的總額
getSum();
})
// 2.2 -號減少數量
$(".decrement").click(function () {
// 一定是當前加號的兄弟表單的值自增
var n = $(this).siblings(".itxt").val();
// 商品數量
n--;
console.log(n);
// 三元表達式:判斷數量不能小於0
n = n <= 0 ? 1 : n;
$(this).siblings(".itxt").val(n);
// 當前+號區域的單價
var p = $(this).parents(".p-num").siblings(".p-price").text();
p = parseFloat(p.substr(1));
console.log(p);
// 獲取當前的總價
var price = $(this).parents(".p-num").siblings(".p-sum").text();
// 去掉¥符號
price = parseFloat(price.substr(1));
price = (p * n).toFixed(2);
console.log(price);
$(this).parents(".p-num").siblings(".p-sum").text("¥" + price);
getSum();
})
做到這裏,能實現點擊-/+按鈕,改變商品數量,對應的小計也發生變化。但是,這裏存在一個bug,就是當用戶自己輸入商品數量時,小計部分的總額是不變化的,這就很驚悚了。
所以,這裏還需要判斷一下用戶改變表單內容的事件。可以用change事件註冊,但是用戶體驗不好,需要在空白處點擊一次小計纔會更新,這裏我用的是鍵盤彈起keyup事件。
// 3. 這樣的話 有一個bug,當用戶自己更改表單的內容時就會出錯
$(".itxt").keyup(function () {
var n = $(this).val();
var p = $(this).parents(".p-num").siblings(".p-price").text();
p = parseFloat(p.substr(1));
var price = $(this).parents(".p-num").siblings(".p-sum").text();
// 去掉¥符號
price = parseFloat(price.substr(1));
price = (p * n).toFixed(2);
console.log(price);
$(this).parents(".p-num").siblings(".p-sum").text("¥" + price);
getSum();
})
4. 結算購物車部分
這部分用到了jQuery元素的遍歷,each()。jQuery中存在的隱式迭代是對不同元素進行相同的操作,現在我們需要對不同的元素做不同的操作,此時我們就需要遍歷元素了。遍歷每個模塊中的商品數量進行累加就是購物車總數量,遍歷每個模塊中的商品小計進行累加就是購物車結算總額。我們可以封裝一個函數,因爲只有有變動我們都需要更新數據,實時更新購物車對應的數據,所以封裝一個函數比較好。這就不難解釋,爲什麼每次點擊-/+按鈕時,需要在最後調用一次本函數了。
注意:只有商品被選中時,纔會參與購物車結算的。
// 封裝一個函數,用來計算小結的內容
function getSum() {
var totalNumber = 0; // 總件數
var totalPrice = 0; // 總價錢
// 遍歷car-item所有的表單中的商品數量 累加 算出所有商品的總數量
$(".itxt").each(function (i, ele) {
// 判斷 商品對應的按鈕是否選中,選中才會結算 不選中不參與結算
var singleBtn = $(this).parents(".p-num").siblings(".p-checkbox").children(".j-checkbox");
if (singleBtn.prop("checked")) {
totalNumber += parseFloat($(ele).val());
}
})
$(".amount-sum em").text(totalNumber);
// 遍歷每個car-item中的商品總計 累加起來算出所有商品價
$(".p-sum").each(function (i, ele) {
var singleBtn = $(this).siblings(".p-checkbox").children(".j-checkbox");
if (singleBtn.prop("checked")) {
totalPrice += parseFloat($(ele).text().substr(1));
}
})
$(".price-sum em").text("¥" + totalPrice.toFixed(2));
}
5.刪除模塊
這部分比較簡單,就是點擊事件的註冊,主要是要找到點擊時,刪除對應的父結構。切記切記,刪除的永遠是當前被點擊按鈕對應的結構,核心就是this的問題。
// 5. 刪除模塊
// 刪除按鈕
$(".p-action a").click(function () {
$(this).parents(".cart-item").remove();
getSum();
})
// 刪除選中的商品
$(".operation .remove-batch").click(function () {
$(".j-checkbox:checked").parents(".cart-item").remove();
getSum();
})
// 清空購物車
$(".operation .clear-all").click(function () {
$(".cart-item").remove();
getSum();
})
刪除第一個後:
點擊刪除所選中商品按鈕:
清空:
最後附上結構代碼,一個商品列部分。
<div class="cart-item">
<div class="p-checkbox">
<input type="checkbox" name="" id="" class="j-checkbox">
</div>
<div class="p-goods">
<div class="p-img">
<img src="upload/p2.jpg" alt="">
</div>
<div class="p-msg">【2000張貼紙】貼紙書 3-6歲 貼畫兒童 貼畫書全套12冊 貼畫 貼紙兒童 汽</div>
</div>
<div class="p-price">¥24.80</div>
<div class="p-num">
<div class="quantity-form">
<a href="javascript:;" class="decrement">-</a>
<input type="text" class="itxt" value="1">
<a href="javascript:;" class="increment">+</a>
</div>
</div>
<div class="p-sum">¥24.80</div>
<div class="p-action"><a href="javascript:;">刪除</a></div>
</div>
完整的html
<div class="c-container">
<div class="w">
<div class="cart-filter-bar">
<em>全部商品</em>
</div>
<!-- 購物車主要核心區域 -->
<div class="cart-warp">
<!-- 頭部全選模塊 -->
<div class="cart-thead">
<div class="t-checkbox">
<input type="checkbox" name="" id="" class="checkall"> 全選
</div>
<div class="t-goods">商品</div>
<div class="t-price">單價</div>
<div class="t-num">數量</div>
<div class="t-sum">小計</div>
<div class="t-action">操作</div>
</div>
<!-- 商品詳細模塊 -->
<div class="cart-item-list">
<div class="cart-item check-cart-item">
<div class="p-checkbox">
<input type="checkbox" name="" id="" checked class="j-checkbox">
</div>
<div class="p-goods">
<div class="p-img">
<img src="upload/p1.jpg" alt="">
</div>
<div class="p-msg">【5本26.8元】經典兒童文學彩圖青少版八十天環遊地球中學生語文教學大綱</div>
</div>
<div class="p-price">¥12.60</div>
<div class="p-num">
<div class="quantity-form">
<a href="javascript:;" class="decrement">-</a>
<input type="text" class="itxt" value="1">
<a href="javascript:;" class="increment">+</a>
</div>
</div>
<div class="p-sum">¥12.60</div>
<div class="p-action"><a href="javascript:;">刪除</a></div>
</div>
<div class="cart-item">
<div class="p-checkbox">
<input type="checkbox" name="" id="" class="j-checkbox">
</div>
<div class="p-goods">
<div class="p-img">
<img src="upload/p2.jpg" alt="">
</div>
<div class="p-msg">【2000張貼紙】貼紙書 3-6歲 貼畫兒童 貼畫書全套12冊 貼畫 貼紙兒童 汽</div>
</div>
<div class="p-price">¥24.80</div>
<div class="p-num">
<div class="quantity-form">
<a href="javascript:;" class="decrement">-</a>
<input type="text" class="itxt" value="1">
<a href="javascript:;" class="increment">+</a>
</div>
</div>
<div class="p-sum">¥24.80</div>
<div class="p-action"><a href="javascript:;">刪除</a></div>
</div>
</div>
<!-- 結算模塊 -->
<div class="cart-floatbar">
<div class="select-all">
<input type="checkbox" name="" id="" class="checkall">全選
</div>
<div class="operation">
<a href="javascript:;" class="remove-batch"> 刪除選中的商品</a>
<a href="javascript:;" class="clear-all">清理購物車</a>
</div>
<div class="toolbar-right">
<div class="amount-sum">已經選<em>1</em>件商品</div>
<div class="price-sum">總價: <em>¥12.60</em></div>
<div class="btn-area">去結算</div>
</div>
</div>
</div>
</div>
</div>