利用localStorage实现
html页面3个分别是
productList 产品列表 details产品详情页 cartList购物车页面
1.productList.html 页面
<style>
body,ul ,li{
padding: 0;
margin: 0;
}
li{
list-style: none;
}
#productDatas li{
float: left;
width: 220px;
padding: 10px;
margin: 10px;
border: 1px solid #000;
}
.btn{
border: none;
width: 120px;
height: 30px;
background: red;
color: #fff;
}
</style>
</head>
<body>
<ul id="productDatas">
<!-- <li>//模板写出 注释掉
<img src="../img/1.jpg" alt="">
<p>标题</p>
<p>价格</p>
<input type="button" value="加入购物车" class="btn">
</li>
<li>
<img src="../img/1.jpg" alt="">
<p>标题</p>
<p>价格</p>
<input type="button" value="加入购物车" class="btn">
</li>
<li>
<img src="../img/1.jpg" alt="">
<p>标题</p>
<p>价格</p>
<input type="button" value="加入购物车" class="btn">
</li> -->
</ul>
</body>
<script src="../js/cart.js"></script>
<script>
/* let productDatas={//先把商品基本信息列出来,然后利用localStorage存到本地 就可以注释掉
"10001":{
id:10001,
imgsrc:"../img/1.jpg",
title:"商品1",
price:100
},
"10002":{
id:10002,
imgsrc:"../img/2.jpg",
title:"商品2",
price:200
},
"10003":{
id:10003,
imgsrc:"../img/3.jpg",
title:"商品3",
price:300
}
}
localStorage.setItem("productDatas",JSON.stringify(productDatas));
*/
//取到本地商品信息,实际开发是从服务器取数据
let productDatas=JSON.parse(localStorage.getItem("productDatas"));
let oProduct=document.getElementById("productDatas");
let str="";
for(let id in productDatas){//利用模板字符串把商品信息显示出来
str+=`
<li>
<a href="details.html?id=${id}"> <img src="${productDatas[id].imgsrc}" alt=""></a>
<p>${productDatas[id].title}</p>
<p>${productDatas[id].price}</p>
<input type="button" value="加入购物车" class="btn" data-id="${id}">
</li>
`;
}
oProduct.innerHTML=str;
let cart=new Cart(); //调用购物车类
let oInput=document.querySelectorAll("input");
for(let i=0;i<oInput.length;i++){
oInput[i].onclick=function(){
let preID=oInput[i].getAttribute("data-id");
cart.saveData(preID,1,false);
}
}
</script>
2.details产品详情页
<body>
<div class="datails"></div>
</body>
<script src="../js/cart.js"></script>
<script>
let oDatails=document.querySelectorAll(".datails")[0];
let prodID=location.search.split("=")[1];//利用location.search.split取到地址后面跟的数据等号右边的就是id
// console.log(prodID);
let productData=JSON.parse(localStorage.getItem("productDatas"))[prodID];//利用id来找到对应的商品的基本信息
// console.log(productData);
oDatails.innerHTML=`//然后放到页面中展示
<img src="${productData.imgsrc}">
<p>${productData.title}</p>
<p>${productData.price}</p>
<span>-</span><input type="text" value="1"><span>+</span>
<input type="button" value="加入购物车" id="btn">
`;
let aSpan=document.querySelectorAll("span");
let aInput=document.querySelectorAll("input");
aSpan[0].onclick=function(){//给页面中减号添加点击效果
aInput[0].value--;
if(aInput[0].value==0){//控制临界值
aInput[0].value=1;
}
}
aSpan[1].onclick=function(){//加号点击效果
//一般会有限购和库存限制
aInput[0].value++;
}
aInput[0].onchange=function(){//文本框数量显示
if(aInput[0].value<=1){
aInput[0].value=1;
}
}
let cart=new Cart();
aInput[1].onclick=function(){//在给加入购物车按钮添加效果
let num=aInput[0].value;
cart.saveData(prodID,+num,false);//把文本框里数量存到本地
location.href="cartList.html";//跳转到购物车列表页面
}
</script>
3.cartList购物车页面
<style>
li{
list-style: none;
}
img{
width: 30px;
}
.del{
background: red;
color: #Fff;
}
</style>
</head>
<body>
<input type="checkbox" id="checkbox">全选//全选框
<br>
<ul id="cartList">//显示商品
</ul>
<div id="totalPrice">//显示所有商品的总价
0
</div>
</body>
<script src="../js/cart.js"></script>
<script>
let cart=new Cart();
cart.showList();
</script>
4.cart.js 创建购物车类 面向对象 上面每个页面都引入此js
class Cart {
constructor() {
//判断cartData里是否有数据
if (localStorage.getItem("cartData")) {//如果有 取出来用
this.cartData = JSON.parse(localStorage.getItem("cartData"));
} else {//如果没有 cartData定义一个空对象
this.cartData = {};
}
}
//num形参变量
saveData(perID, num, flag) {//判断caraData有没有这个id的值 //flag为true时,num为终值,为false时,num为累加值
if (!this.cartData[perID] || flag) {//如果没有给这个id赋值num
this.cartData[perID] = num;
} else {//有num累加
this.cartData[perID] += num;
}
localStorage.setItem("cartData", JSON.stringify(this.cartData));//把cartData数据存到本地
}
showList() {//购物车页面展示
this.oCheck = document.getElementById("checkbox");
this.cartList = document.getElementById("cartList");
this.totalPrice = document.getElementById("totalPrice");//获取DOM对象
let productDatas = JSON.parse(localStorage.getItem("productDatas"));//获取本地商品数据
let str = "";
for (let id in this.cartData) {//遍历cartData数据里的id,来匹配添加的商品 再把商品展示出来
str += `
<li data-id="${id}">
<input type="checkbox" class="ck">
<img src="${productDatas[id].imgsrc}">
<span>${productDatas[id].title}</span>
<span class="perPrice">${productDatas[id].price}</span>
<span class="minus">-</span>
<input type="text" value="${this.cartData[id]}" class="num">
<span class="plus">+</span>
<span class="total">${productDatas[id].price*this.cartData[id]}</span>
<span class="del">删除</span>
</li>
`;
}
cartList.innerHTML = str;
//给需要操作的DOM对象添加类名,在获取它们
this.ck = document.querySelectorAll(".ck");
this.perPrice = document.querySelectorAll(".perPrice");
this.minus = document.querySelectorAll(".minus");
this.num = document.querySelectorAll(".num");
this.plus = document.querySelectorAll(".plus");
this.total = document.querySelectorAll(".total");
this.del = document.querySelectorAll(".del");
this.list = document.querySelectorAll("li");
//全选
this.oCheck.onclick = () => { //列表里的每一个复选框的状态要和全选复选框状态保持一致
for (let i = 0; i < this.ck.length; i++) {
//遍历是取到所有列表的复选框,checked是选中状态
this.ck[i].checked = this.oCheck.checked;
}
this.totalPrices();
}
for (let i = 0; i < this.ck.length; i++) {
this.ck[i].onclick = () => { //判断单个复选框被勾选的数量和复选框的总量是否一致
let count = 0;//表示勾选的数量默认为0
for (let j = 0; j < this.ck.length; j++) {
if (this.ck[j].checked) { //勾选count+1
count++;
}
}
//循环结束之后,能算出有多少个勾选的,如果这个勾选的数量和所有复选框的数量相同
if (count == this.ck.length) { //当count等于this.ck的长度时,全选框勾选
this.oCheck.checked = true;
} else {
this.oCheck.checked = false;
}
this.totalPrices();
}
}
//减号
for (let i = 0; i < this.minus.length; i++) {//遍历减号,因为加号和文本框和删除按钮跟它数量一致,所以只用一次循环
this.minus[i].onclick = () => {//给每个减号添加点击事件
this.num[i].value--; //文本框里的值减一
if (this.num[i].value == 0) { //控制数量的临界值
this.num[i].value = 1;
}
this.upData(i);//调用upData方法
this.totalPrices();//改变商品总价的方法
}
//加号
this.plus[i].onclick = () => {//给每个加号添加点击事件
this.num[i].value++; //文本框值加一
this.upData(i);
this.totalPrices();
}
//文本框
this.num[i].onchange=()=>{
if(this.num[i].value<=1){
this.num[i].value=1;
}
this.upData(i);
this.totalPrices();
}
//删除
this.del[i].onclick=()=>{
let prodID=this.list[i].getAttribute("data-id");
this.delData(prodID,i);
}
}
}
upData(i) {
//单种商品的总价改变
this.total[i].innerText = this.perPrice[i].innerText * this.num[i].value;
//购物车数据的改变并保存
let perID = this.list[i].getAttribute("data-id");
this.saveData(perID, +this.num[i].value, true);
}
totalPrices() {//改变总价
let totalPrice = 0;
for (let j = 0; j < this.ck.length; j++) {
//找到所有勾选的商品单个总价,进行累加
if (this.ck[j].checked) {
totalPrice += +this.total[j].innerText;
}
}
this.totalPrice.innerText = totalPrice;
}
//删除
delData(prodID,i){
//根据id删除对应项
delete this.cartData[prodID];
//在存到本地 正常操作是存到服务器
localStorage.setItem("cartData",JSON.stringify(this.cartData));
//删除DOM节点
this.cartList.removeChild(this.list[i]);
this.ck[i].checked=false;//因为删除DOM结构,页面上的结构消失,但是变量(this.list/this.ck等)里存的值并没有减少,
//状态没有改变,如果这里也要改变总价,为了保证删除掉的商品不要再被计算在内,需要报对应的复选框的状态置为false
this.totalPrices();//然后调用计算总价的方法
}
}