localStorage
在HTML5中,新加入了一个localStorage特性,这个特性主要是用来作为本地存储来使用的,解决了cookie存储空间不足的问题(cookie中每条cookie的存储空间为4k),localStorage中一般浏览器支持的是5M大小,这个在不同的浏览器中localStorage会有所不同,且用它来保存的数据没有过期时间,直到手动去删除,所以用他来长久的保存购物车中的数据,是一个非常棒的方法
实现加入购物车将数据存在localStorage中的功能解析
*首先要先获取到商品的详细数据,然后就可以使用localStorage来存储这个数据了(注意:localString中只能存放字符串格式的数据,所以我们要把数据编译为字符串类型,推荐使用严格json格式字符串)
*详情数据由我们选择商品后在页面中获取到商品名,颜色,大小,价格还有数量等商品属性后,编译为JSON格式字符串保存到localStorage中
往localStorage中存放数据的实现思想:
首先先将获取到的商品详细信息编译为json对象,然后判断一下localStrong中是否已存在数据(即购物车是否为空)
*若不存在则将已经编译好的json对象格式的新数据以数组的形式(即将这个新数据放到数组中)转为json字符串,然后再存储到localStorage中
*若localStorage中已存在数据,则将localStorage中的数据取出来,因为取出来的数据是字符串格式的所以要先将其转为原格式即转回为数组后方可进行下一步的操作,然后就可以将已经编译好localStorage新数据用数组push()的方法将其添加在这个数组中(这样原先的数据就不会被覆盖掉了,数组中允许出现重复元素),最后再将其转为json字符串并重新添加在localStorage中就OK了
那么如何判断购物车中是否已存在此商品了呢
这里我们可以使用js数组的some方法来判断转回为数组的localStorage数据中是否存在这条数据(判断的条件为:可以对商品造成重大影响的属性值是否相等,eg:id color 还有 Size 都可对商品造成重大影响)
* 可使用判断条件
* 原数据.id === 新数据.id 原数据.color === 新数据.color 原数据.Size === 新数据.Size 等
* 若经过some方法判断后的条件为true,则代表购物车中存在相同数据(即id color 还有 Size都相等),但是他们的num值不相等,所以我们就需要把原数据中的num值取出来然后合并到新数据的num值上并将原数据删除,然后再将新数据用数组push()的方法添加到数组中,然后保存到localStorang中即可
* 若是判断后的条件为 false (即some方法只要是其中有一个条件不满足就直接false),则就直接可以将这条新数据直接push()添加在数组中并保存到localStroang中即可
*
* some方法:
* Array.some(函数)
* some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。
* some() 方法会依次执行数组的每个元素:
* 如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。
* 如果没有满足条件的元素,则返回false。
* 注意: some() 不会对空数组进行检测。
* 注意: some() 不会改变原始数组。
HTML代码
<!-- 商品展示区 -->
<div id="Commodity">
<ul>
<li>id</li>
<li>商品名</li>
<li>价格</li>
<li>颜色</li>
<li>尺码</li>
<li>数量</li>
<li>操作</li>
</ul>
<ul class="commodity">
<li class="id">1</li>
<li class="name">短袖</li>
<li class="price">2500</li>
<li class="color">红色</li>
<li class="size">M</li>
<li class="number">
<span class="reduce">-</span>
<span class="num">0</span>
<span class="plus">+</span>
</li>
<li>
<button class="Add">加入到购物车</button>
</li>
</ul>
<ul class="commodity">
<li class="id">2</li>
<li class="name">外套</li>
<li class="price">1800</li>
<li class="color">黑色</li>
<li class="size">XXL</li>
<li class="number">
<span class="reduce">-</span>
<span class="num">0</span>
<span class="plus">+</span>
</li>
<li>
<button class="Add">加入到购物车</button>
</li>
</ul>
<ul class="commodity">
<li class="id">3</li>
<li class="name">裤子</li>
<li class="price">1600</li>
<li class="color">蓝色</li>
<li class="size">L</li>
<li class="number">
<span class="reduce">-</span>
<span class="num">0</span>
<span class="plus">+</span>
</li>
<li>
<button class="Add">加入到购物车</button>
</li>
</ul>
</div>
<!-- 购物车展示区 -->
<div id="ShoppingCart">
<ul>
<li>商品名</li>
<li>价格</li>
<li>颜色</li>
<li>尺码</li>
<li>数量</li>
</ul>
<div id="DisplayInformation">
<!-- 购物车内容显示区 -->
<!-- 写好样式以后,使用jq动态创建ul li 并一一填入数据然后再放到这个后边即可 -->
</div>
</div>
CSS代码
<style>
*{
margin: 0;
padding: 0;
}
/*商品展示区*/
#Commodity{
width: 724px;
margin-bottom: 20px;
}
#Commodity ul{
list-style: none;
display: flex;
justify-content: space-between;
background-color: aqua;
}
#Commodity ul li{
width: 100px;
margin: 2px;
text-align: center;
line-height: 50px;
background-color: burlywood;
}
#Commodity ul li span{
display: inline-block;
line-height: 20px;
}
#Commodity ul li span:nth-of-type(1),#Commodity ul li span:nth-of-type(3){
width: 17px;
height: 20px;
background-color: #d9d9d9;
border: 1px solid #b3b3b3;
margin: 4px;
cursor: pointer;
}
#Commodity ul li span:nth-of-type(2){
width: 32px;
height: 20px;
border: 1px solid #d9d9d9;
}
.Add{
width: 100%;
height: 100%;
border: none;
background-color: #d9d9d9;
cursor: pointer;
}
/*购物车展示区*/
#ShoppingCart{
margin-top: 50px;
width: 724px;
}
#ShoppingCart ul{
list-style: none;
display: flex;
justify-content: space-between;
background-color: rgb(33, 199, 47);
}
#ShoppingCart ul li{
width: 150px;
margin: 2px;
text-align: center;
line-height: 50px;
background-color: burlywood;
}
</style>
JS代码(基于jQuery3.4.1版本)
<script>
//实现加入购物车将数据存在localStorage中的功能解析
/**
* 首先获取这个按钮
* 然后点击这个按钮的时候获取商品详情数据,然后使用localStorage存储这个数据(注意:localString中只能存放字符串格式的数据,所以我们要把数据编译为字符串类型,推荐使用严格json格式字符串)
* 详情数据由我们选择商品后在页面中获取到商品名,颜色,大小,价格还有数量等商品属性后,编译为JSON格式字符串保存到localStorage中
*/
/* 往localStorage中存放数据的实现思想:*/
/**
* 首先先将获取到的商品详细信息编译为json对象,然后判断一下localStrong中是否已存在数据(即购物车是否为空)
* 若不存在则将已经编译好的json对象格式的新数据以数组的形式(即将这个新数据放到数组中)转为json字符串,然后再存储到localStorage中
* 若localStorage中已存在数据,则将其中的数据取出来,因为取出的数据是字符串格式的所以要先将其转为原格式即转回为数组后方可进行下一步的操作,然后就可以将已经编译好localStorage新数据用数组push()的方法将其添加在这个数组中(这样原先的数据就不会被覆盖掉了,数组中允许出现重复元素),最后再将其转为json字符串并重新添加在localStorage中就OK了
*/
/**
* 那么如何判断购物车中是否已存在相同的数据呢,这里我们可以使用js数组的some方法来判断转回为数组的localStorage数据中是否存在这条数据(判断的条件为:可以对商品造成重大影响的属性值是否相等,eg:id color 还有 Size 都可对商品造成重大影响)
* 可使用判断条件
* 原数据.id === 新数据.id 原数据.color === 新数据.color 原数据.Size === 新数据.Size
* 若经过some方法判断后的条件为true,则代表购物车中存在相同数据(即id color 还有 Size都相等),但是他们的num不相等,所以我们就需要把原数据中的num值取出来然后合并到新数据的num值上并将原数据删除,然后再将新数据用数组push()的方法添加到数组中,然后保存到localStorang中即可
* 若是判断后的条件为 false (即some方法只要是其中有一个条件不满足就直接false),则就直接可以将这条新数据直接push()添加在数组中并保存到localStroang中即可
*
* some方法:
* Array.some(函数)
* some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。
* some() 方法会依次执行数组的每个元素:
* 如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。
* 如果没有满足条件的元素,则返回false。
* 注意: some() 不会对空数组进行检测。
* 注意: some() 不会改变原始数组。
*/
//第一步:获取页面元素
let oAdd = $('.Add');//添加购物车按钮
let oLook = $('#look');//查看购物车按钮
let oPlus = $('.plus');//商品加
let oReduce = $('.reduce');//商品减
console.log(oPlus.length);
//第二步 添加事件
/**
* 点击 + - 对商品数量进行操作
* - 到最少 0 个商品不能为负
*/
// + 按钮点击事件
$(oPlus).each(function(index,value){//JQ循环遍历每一个增加num的按钮
/**
* 当点击增加按钮的时候此按钮的上一级兄弟元素中的值加一
* JQ获取当前节点的上一个兄弟节点 节点.prev()
*/
$(this).on('click',() => {//对每个按钮都进行增加的功能,无上限,当前this指向当前oPlus
let num = parseInt($(this).prev().html());//获取当前商品的num值,JQ获取当前元素的紧邻的前一个兄弟元素prev()
num ++;//每点击一次num + 1;
$(this).prev().html(num);//然后将改变过的num值重新更改到当前元素的前一个兄弟元素中(即num框中)
})
})
// - 按钮点击事件
$(oReduce).each(function(index,value){
/**
* 当点击减少的按钮的时候,首先先判断一下他的后一个兄弟元素中的值是否已经为0了,若为0了就直接赋值为0,不能让其继续减少,如若大于0则每点击一次减一
* JQ获取当前元素的后一个兄弟元素 节点.next()
*/
$(this).on('click',() => {
let num = parseInt($(this).next().html());
if(num === 0){
num = 0;
$(this).next().html(num);
}
if(num > 0){
num --;
$(this).next().html(num);
}
})
})
/**
* 当点击加入购物车按钮时,实现将当前按钮元素所在父级元素下的所有元素中的当前商品的详细信息存储在localStorage中
* 实现步骤
* 1.先获取到当前元素所在父元素(即li)的父元素(即ul)下的所有的商品属相值
* 2.然后将获取到的商品信息使用JSON对象的方法编辑为一条新数据,然后将其保存在数组中(暂且称这条数据为新数据)
* 3.然后判断购物车即localStorage中是否为空,若为空则就可以直接将这条新数据保存在localStorage中,若不为空则继续往下判断购物车中数据是否有重复元素,方法如下:
* 将localStorage中的数据使用localStorage.getItem()的方法扒拉下来,然后使用js的JSON对象的方法JSON.parse()的方法将信息重新转回为数组,然后使用js数组的some()方法来判断数组中是否存在我们所要添加的这条新数据(主要判断 id color 和 Size是否一致),若已存在原数据(我们暂且称这条已存在数据为原数据),则将原数据这个对象中的num属性值取出来并合并到新数据中,然后通过数组改的方法:splice(下标的开始位置,删除的数组长度,新增的元素,新增元素,……)删掉原数据,然后再将新数据通过数组push()添加的方法添加到数组中,最后再将这个数组转为json字符串重新保存再localSorage中即可
*/
//加入到购物车按钮添加点击事件
$(oAdd).each(function(index,value){
$(this).on('click',() => {
/**
* 获取当前元素的父元素下得商品属性值并编译为JSON对象格式的数据
*/
let oUl = $(this).parent().parent()//当前按钮的父元素的父元素即为ul标签
let id = oUl.children('.id').html();//JQ方法获取当前元素下的所有子元素,参数用来规定选择范围,此段语句为匹配ul标签下class名为id的标签,html():JQ方法,获取元素内容
let name = oUl.children('.name').html();
let price = oUl.children('.price').html();
let color = oUl.children('.color').html();
let size = oUl.children('.size').html();
let num = oUl.children('.number').children('.num').html();
// console.log(id,name,price,color,size,num)
let obj = {
"id":id,
"name":name,
"price":price,
"color":color,
"size":size,
"num":num
}
/**
* 获取保存在localStorage中的数据
*/
let cart = window.localStorage.getItem('cart');
console.log('localstorage中的数据',cart);
if(cart){//存在数据,即购物车不为空
console.log('购物车不为空,执行判断是否有重复数据操作');
//然后将获取到的localStorage数据转回为数组
let arr = JSON.parse(cart);
console.log('重新转回为数组的localStorage数据',arr);
//然后使用数组some的方法判断是否存在重复数据,返回值为布尔值
let condition = arr.some(function (item, index, array) {//回调函数有三个参数:1.数组中的元素,2.下标,3.数组本身
return item.id === obj.id && item.color === obj.color && item.size === obj.size;//返回一个经过条件判断之后的一个结果,布尔值
});
console.log('判断后的返回值',condition);
if(condition){
console.log('判断结果为true执行原数据新数据合并操作');
$(arr).each(function(index,value){//循环遍历这个数组寻找与新数据匹配的元素
if(obj.id === value.id && obj.color === value.color && obj.size === value.size){
//将原新数据的num值合并
obj.num = parseInt(obj.num) + parseInt(value.num);
//删除原数据
arr.splice(index, 1);//删除原数据
arr.push(obj);//新数据增填到数组中
window.localStorage.setItem('cart',JSON.stringify(arr));
}
})
}else{
console.log('判断结果为false直接执行将新数据上传到localStorage中的操作');
arr.push(obj);
window.localStorage.setItem('cart',JSON.stringify(arr));
}
}else{
console.log('购物车为空执行直接加入往localStorage中添加数据功能');
let arr = [obj];
window.localStorage.setItem('cart', JSON.stringify(arr))//使用localStrong的setItem来往localStrong中存放数据(两个参数:name,value)
}
ShowCart();//每点击一次调用一次显示购物车功能函数
})
})
//商品显示区功能
/**
* 加载完页面后读取localStorage中的数据并填写到商品显示区中的#DisplayInformation标签中
* 当点击加入购物车按钮的时候重新加载(即调用这个显示方法然后删除掉#DisplayInformation标签然后再重新创建这个div并将数据显示到这个里边)
*/
ShowCart();//先调用一次,页面加载完直接显示
function ShowCart(){
//1.先删除一遍#DisplayInformation标签中#DisplayUl标签然后再重新创建
$('.DisplayUl').remove();
//取出localStorage中的数据并转回为数组形式
let arr = JSON.parse(window.localStorage.getItem('cart'));
$.each(arr, function (index, value) {//each循环遍历数组,将数据一一对应添加到#DisplayInformation中并显示到页面中
/**
* .append() JQ方法 在每个匹配元素里面的末尾处插入参数内容。
*/
$('#DisplayInformation').append(`
<ul class="DisplayUl">
<li>${value.name}</li>
<li>${value.price}</li>
<li>${value.color}</li>
<li>${value.size}</li>
<li>${value.num}</li>
</ul>
`);
})
}
</script>