【学习笔记46】JavaScript购物车的实现


一、案例效果

1、将通过数据重构页面

  • 查询数据, 渲染页面
    图片[1] - 【学习笔记46】JavaScript购物车的实现 - MaxSSL

2、全选

  1. 选中全选按钮后, 根据全选按钮的选中状态, 修改所有商品的选中状态
  2. 重新渲染视图

图片[2] - 【学习笔记46】JavaScript购物车的实现 - MaxSSL

图片[3] - 【学习笔记46】JavaScript购物车的实现 - MaxSSL

3、清空购物车

  1. 清空商品数据
  2. 重新渲染视图

图片[4] - 【学习笔记46】JavaScript购物车的实现 - MaxSSL

图片[5] - 【学习笔记46】JavaScript购物车的实现 - MaxSSL

4、结算

  1. 找到所有选中的商品
  2. 计算所有选中商品各自的总价
  3. 计算所有选中商品的总价之和

图片[6] - 【学习笔记46】JavaScript购物车的实现 - MaxSSL

5、删除已选中

  1. 在原数组中, 找到选中的商品, 然后删除
  2. 重新渲染视图

图片[7] - 【学习笔记46】JavaScript购物车的实现 - MaxSSL

图片[8] - 【学习笔记46】JavaScript购物车的实现 - MaxSSL

6、商品数量调整

  1. 找到对应的商品, 修改收藏数量
  2. 重新渲染视图

图片[9] - 【学习笔记46】JavaScript购物车的实现 - MaxSSL

图片[10] - 【学习笔记46】JavaScript购物车的实现 - MaxSSL

7、选中商品

  1. 找到对应的商品, 修改选中状态
  2. 重新渲染视图

图片[11] - 【学习笔记46】JavaScript购物车的实现 - MaxSSL

8、删除某一项

  1. 找到对应商品, 将删除
  2. 重新渲染视图

图片[12] - 【学习笔记46】JavaScript购物车的实现 - MaxSSL

图片[13] - 【学习笔记46】JavaScript购物车的实现 - MaxSSL

9、数据持久化 (浏览器关闭, 数据能保存)

  • 本地存储
    图片[14] - 【学习笔记46】JavaScript购物车的实现 - MaxSSL

二、案例分析

1. 数组数据分析

  1. id: 数据的唯一值
  2. status: true代表该商品被选中, false则为没被选中
  3. pic: 图片地址
  4. name: 商品名
  5. price: 价格
  6. number: 商品收藏数量
  7. total: 库存

2. 数据驱动视图

  • 查: 查询数据, 渲染到页面
  • 增删改: 找到源数据, 然后对源数据做修改, 修改完成, 重新渲染页面

3. 逻辑思维

  1. 准备一个渲染函数
  2. 首次打开页面时 调用
  3. 在各种事件触发之后, 重新调用

三、html代码

<div class="header">页面顶部</div><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代码的实现

// 获取localStorage的数据时, 为了避免首次进入页面没有数据, 所以通过逻辑或给一个本地数据兜底var cartList = JSON.parse(window.localStorage.getItem("cartList")) || [// 每一个对象就是一个购物车内容的数据{id: 111234,status: true,pic: "https://img1.baidu.com/it/u=2511310783,721605137&fm=253&fmt=auto&app=138&f=JPEG" />,name: "我是一个手机, 不知道是啥",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: "我是一个电脑, 不知道是啥",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: "我是一个手纸, 不知道是啥",price: 356.21,number: 2,total: 22,},];// 1. 获取标签对称const oContent = document.querySelector('.content');// 2. 封装函数 渲染页面function myPage() {// 定义变量 存储数据let selectItem = 0; //存储选中商品的数量let selectTotalNum = 0; //存储选中商品的总数量let totalPrice = 0; //存储选中商品的总价格// 找到选中的商品cartList.forEach(function (item) {if (item.status == true) {selectItem++;selectTotalNum += item.number;totalPrice += item.price * item.number;}})// 查找数据 渲染页面// 选中的商品数量 如果代表商品总量 代表所有商品被选中var str = `<input type="checkbox" class="checkAll" ${selectItem === cartList.length ? "checked" : ""}> 全选`;cartList.forEach(function (item) {str += `
  • <input type="checkbox" class="checkOther" data-id="${item.id}"${item.status ? "checked" : ""}><img class="aligncenter" src="https://www.maxssl.com/uploads/?url=${item.pic}" >${item.name}${item.price.toFixed(2)}<button class="reduce-btn"data-id="${item.id}">-<input type="text" value="${item.number}"><button class="increase-btn" data-id="${item.id}">+¥ ${(item.number * item.price).toFixed(2)}<button class="del" data-id="${item.id}">删除
`
;})str += `总件数 : ${selectTotalNum}<button class="payment" data-totalPrice="${totalPrice}"">去结算总价格 : ¥ ${totalPrice.toFixed(2)}`;oContent.innerHTML = str;// 将数据存储到localStorage中 便于下次进入可以获取上一次的数据window.localStorage.cartList = JSON.stringify(cartList);// window.localStorage.setItem("cartList", JSON.stringify(cartList));}// 调用函数 渲染页面(页面首次打开页面)myPage()// 3. 购物车的功能实现// 利用事件冒泡 把事件委托给统一的父级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) {//购物车的数据为空cartList = [];// 渲染页面myPage()}}// 结算(将选择的商品总价计算打印到控制台)if (e.target.className === 'payment') {// console.log(e.target.dataset.totalprice);var price = e.target.dataset.totalprice;price = Math.round(price)confirm(`总价格为:${price}`)}// 删除所有已选中(没有选中时 禁止执行)if (e.target.className === 'delCheck') {var warn = confirm('您确定要删除当前选择的吗')if (!warn) return;// 过滤数组 只留下选中状态为falsecartList = cartList.filter(function (item) {return !item.status})// 渲染页面myPage()}// 减少商品的数量if (e.target.className === 'reduce-btn') {// 减少商品数量 不能为0cartList.forEach(function (item) {// 通过商品的ID找到点击的是哪一个商品 累减操作if (item.id == e.target.dataset.id && item.number >= 2) item.number--;})// 渲染页面myPage();}// 增加商品的数量if (e.target.className === 'increase-btn') {cartList.forEach(function (item) {// 通过商品的ID找到点击的是哪一个商品 累加操作if (item.id == e.target.dataset.id && item.number < item.total) item.number++;})// 渲染页面myPage();}// 选中商品if (e.target.className === 'checkOther') {// 遍历数组找到要修改的商品cartList.forEach(function (item) {if (item.id == e.target.dataset.id) {// 修改商品的选中状态item.status = !item.status;}})// 渲染页面myPage()}// 删除某一项商品if (e.target.className === 'del') {var warn = confirm('您确定要删除当前的商品吗');if(!warn) return;// 遍历数组 找到需要删除的项 将其过滤cartList = cartList.filter(function(item){return item.id != e.target.dataset.id;})// 渲染页面myPage()}})
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享