一、案例效果
1、將通過數(shù)據(jù)重構(gòu)頁面
- 查詢數(shù)據(jù), 渲染頁面
2、全選
- 選中全選按鈕后, 根據(jù)全選按鈕的選中狀態(tài), 修改所有商品的選中狀態(tài)
- 重新渲染視圖
3、清空購物車
- 清空商品數(shù)據(jù)
- 重新渲染視圖
4、結(jié)算
- 找到所有選中的商品
- 計(jì)算所有選中商品各自的總價(jià)
- 計(jì)算所有選中商品的總價(jià)之和
5、刪除已選中
- 在原數(shù)組中, 找到選中的商品, 然后刪除
- 重新渲染視圖
6、商品數(shù)量調(diào)整
- 找到對(duì)應(yīng)的商品, 修改收藏?cái)?shù)量
- 重新渲染視圖
7、選中商品
- 找到對(duì)應(yīng)的商品, 修改選中狀態(tài)
- 重新渲染視圖
8、刪除某一項(xiàng)
- 找到對(duì)應(yīng)商品, 將刪除
- 重新渲染視圖
文章來源:http://www.zghlxwxcb.cn/news/detail-479236.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-479236.html
9、數(shù)據(jù)持久化 (瀏覽器關(guān)閉, 數(shù)據(jù)能保存)
- 本地存儲(chǔ)
二、案例分析
1. 數(shù)組數(shù)據(jù)分析
- id: 數(shù)據(jù)的唯一值
- status: true代表該商品被選中, false則為沒被選中
- pic: 圖片地址
- name: 商品名
- price: 價(jià)格
- number: 商品收藏?cái)?shù)量
- total: 庫存
2. 數(shù)據(jù)驅(qū)動(dòng)視圖
- 查: 查詢數(shù)據(jù), 渲染到頁面
- 增刪改: 找到源數(shù)據(jù), 然后對(duì)源數(shù)據(jù)做修改, 修改完成, 重新渲染頁面
3. 邏輯思維
- 準(zhǔn)備一個(gè)渲染函數(shù)
- 首次打開頁面時(shí) 調(diào)用
- 在各種事件觸發(fā)之后, 重新調(diào)用
三、html代碼
<div class="header">頁面頂部</div>
<!-- 動(dòng)態(tài)生成數(shù)據(jù) -->
<div class="content"></div>
<div class="footer">頁面底部</div>
<script src="./index.js"></script>
四、css代碼
* {
margin: 0;
padding: 0;
}
ul,ol,li {
list-style: none;
}
.header,.footer {
width: 1200px;
height: 100px;
background-color: skyblue;
color: #fff;
font-size: 50px;
display: flex;
justify-content: center;
align-items: center;
margin: 0 auto;
}
.footer {
height: 400px;
}
.content {
width: 1200px;
margin: 0 auto;
padding: 10px 0;
}
.content > .top,.content > .bottom {
height: 50px;
background-color: pink;
display: flex;
align-items: center;
}
.content > .bottom {
justify-content: space-between;
box-sizing: border-box;
padding: 0 10px;
}
.content > .bottom > .totalPrice > span {
font-size: 20px;
color: red;
}
.content > .bottom > .btns > button {
font-size: 18px;
padding: 5px 10px;
cursor: pointer;
}
.content > .top > input {
width: 30px;
height: 30px;
margin: 0 15px 0 50px;
}
.content > ul {
padding-top: 10px;
}
.content > ul > li {
width: 100%;
border: 1px solid #333;
box-sizing: border-box;
height: 100px;
margin-bottom: 10px;
display: flex;
}
.content > ul > li > div {
display: flex;
justify-content: center;
align-items: center;
border-right: 1px solid #333;
}
.content > ul > li > div:last-child {
border: none;
}
.content > ul > li > .show,
.content > ul > li > .status {
width: 100px;
}
.content > ul > li > .status > input {
width: 30px;
height: 30px;
}
.content > ul > li > .show > img {
width: 100%;
height: 100%;
display: block;
}
.content > ul > li > .price,
.content > ul > li > .sub {
width: 200px;
color: red;
font-size: 20px;
}
.content > ul > li > .title {
width: 300px;
align-items: flex-start;
justify-content: flex-start;
box-sizing: border-box;
padding: 5px;
}
.content > ul > li > .number {
width: 230px;
}
.content > ul > li > .number > input {
width: 50px;
height: 30px;
text-align: center;
margin: 0 5px;
border: none;
outline: none;
font-size: 18px;
}
.content > ul > li > .number > button {
width: 30px;
height: 30px;
cursor: pointer;
}
.content > ul > li > .destroy {
flex: 1;
}
.content > ul > li > .destroy > button {
padding: 5px;
font-size: 18px;
cursor: pointer;
}
五、js代碼的實(shí)現(xiàn)
// 獲取localStorage的數(shù)據(jù)時(shí), 為了避免首次進(jìn)入頁面沒有數(shù)據(jù), 所以通過邏輯或給一個(gè)本地?cái)?shù)據(jù)兜底
var cartList = JSON.parse(window.localStorage.getItem("cartList")) || [
// 每一個(gè)對(duì)象就是一個(gè)購物車內(nèi)容的數(shù)據(jù)
{
id: 111234,
status: true,
pic: "https://img1.baidu.com/it/u=2511310783,721605137&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=332",
name: "我是一個(gè)手機(jī), 不知道是啥",
price: 100,
number: 3,
total: 16,
},
{
id: 123456,
status: false,
pic: "https://img1.baidu.com/it/u=1537709578,2453227648&fm=253&fmt=auto&app=120&f=JPEG?w=809&h=500",
name: "我是一個(gè)電腦, 不知道是啥",
price: 98.72,
number: 1,
total: 7,
},
{
id: 965874,
status: true,
pic: "https://img2.baidu.com/it/u=3561506717,735421650&fm=253&fmt=auto&app=138&f=JPEG?w=750&h=500",
name: "我是一個(gè)手紙, 不知道是啥",
price: 356.21,
number: 2,
total: 22,
},
];
// 1. 獲取標(biāo)簽對(duì)稱
const oContent = document.querySelector('.content');
// 2. 封裝函數(shù) 渲染頁面
function myPage() {
// 定義變量 存儲(chǔ)數(shù)據(jù)
let selectItem = 0; //存儲(chǔ)選中商品的數(shù)量
let selectTotalNum = 0; //存儲(chǔ)選中商品的總數(shù)量
let totalPrice = 0; //存儲(chǔ)選中商品的總價(jià)格
// 找到選中的商品
cartList.forEach(function (item) {
if (item.status == true) {
selectItem++;
selectTotalNum += item.number;
totalPrice += item.price * item.number;
}
})
// 查找數(shù)據(jù) 渲染頁面
// 選中的商品數(shù)量 如果代表商品總量 代表所有商品被選中
var str = `
<div class="top">
<input type="checkbox" class="checkAll" ${selectItem === cartList.length ? "checked" : ""}> 全選
</div>
`;
cartList.forEach(function (item) {
str += `
<ul>
<li>
<div class="status">
<input type="checkbox" class="checkOther" data-id="${item.id}" ${item.status ? "checked" : ""}>
</div>
<div class="show">
<img src="${item.pic}" alt="">
</div>
<div class="title">${item.name}</div>
<div class="price">¥ ${item.price.toFixed(2)}</div>
<div class="number">
<button class="reduce-btn" data-id="${item.id}">-</button>
<input type="text" value="${item.number}">
<button class="increase-btn" data-id="${item.id}">+</button>
</div>
<div class="sub">¥ ${(item.number * item.price).toFixed(2)}</div>
<div class="destroy">
<button class="del" data-id="${item.id}">刪除</button>
</div>
</li>
</ul>
`;
})
str += `
<div class="bottom">
<div class="totalNum">總件數(shù) : ${selectTotalNum}</div>
<div class="btns">
<button class="clearShopCart">清空購物車</button>
<button class="payment" data-totalPrice="${totalPrice}"">去結(jié)算</button>
<button class="delCheck">刪除所有已選中</button>
</div>
<div class="totalPrice">
總價(jià)格 : ¥ <span>${totalPrice.toFixed(2)}</span>
</div>
</div>
`;
oContent.innerHTML = str;
// 將數(shù)據(jù)存儲(chǔ)到localStorage中 便于下次進(jìn)入可以獲取上一次的數(shù)據(jù)
window.localStorage.cartList = JSON.stringify(cartList);
// window.localStorage.setItem("cartList", JSON.stringify(cartList));
}
// 調(diào)用函數(shù) 渲染頁面(頁面首次打開頁面)
myPage()
// 3. 購物車的功能實(shí)現(xiàn)
// 利用事件冒泡 把事件委托給統(tǒng)一的父級(jí)
oContent.addEventListener('click', function (e) {
// 全選效果
if (e.target.className === 'checkAll') {
cartList.forEach(function (item) {
console.log(e.target.checked);
item.status = e.target.checked;
})
// 渲染頁面
myPage()
}
// 清空購物車
if (e.target.className === 'clearShopCart') {
var warn = confirm('您確定要清空購物車嗎')
if (warn) {
//購物車的數(shù)據(jù)為空
cartList = [];
// 渲染頁面
myPage()
}
}
// 結(jié)算(將選擇的商品總價(jià)計(jì)算打印到控制臺(tái))
if (e.target.className === 'payment') {
// console.log(e.target.dataset.totalprice);
var price = e.target.dataset.totalprice;
price = Math.round(price)
confirm(`總價(jià)格為:${price}`)
}
// 刪除所有已選中(沒有選中時(shí) 禁止執(zhí)行)
if (e.target.className === 'delCheck') {
var warn = confirm('您確定要?jiǎng)h除當(dāng)前選擇的嗎')
if (!warn) return;
// 過濾數(shù)組 只留下選中狀態(tài)為false
cartList = cartList.filter(function (item) {
return !item.status
})
// 渲染頁面
myPage()
}
// 減少商品的數(shù)量
if (e.target.className === 'reduce-btn') {
// 減少商品數(shù)量 不能為0
cartList.forEach(function (item) {
// 通過商品的ID找到點(diǎn)擊的是哪一個(gè)商品 累減操作
if (item.id == e.target.dataset.id && item.number >= 2) item.number--;
})
// 渲染頁面
myPage();
}
// 增加商品的數(shù)量
if (e.target.className === 'increase-btn') {
cartList.forEach(function (item) {
// 通過商品的ID找到點(diǎn)擊的是哪一個(gè)商品 累加操作
if (item.id == e.target.dataset.id && item.number < item.total) item.number++;
})
// 渲染頁面
myPage();
}
// 選中商品
if (e.target.className === 'checkOther') {
// 遍歷數(shù)組找到要修改的商品
cartList.forEach(function (item) {
if (item.id == e.target.dataset.id) {
// 修改商品的選中狀態(tài)
item.status = !item.status;
}
})
// 渲染頁面
myPage()
}
// 刪除某一項(xiàng)商品
if (e.target.className === 'del') {
var warn = confirm('您確定要?jiǎng)h除當(dāng)前的商品嗎');
if(!warn) return;
// 遍歷數(shù)組 找到需要?jiǎng)h除的項(xiàng) 將其過濾
cartList = cartList.filter(function(item){
return item.id != e.target.dataset.id;
})
// 渲染頁面
myPage()
}
})
到了這里,關(guān)于【學(xué)習(xí)筆記46】JavaScript購物車的實(shí)現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!