实现效果:
1. 鼠标的移入与移出: 当鼠标放到购物车上时,购物车向左移动,并展示购物车中的商品
2. 删除键:点击删除,可以在购物车中删除这个商品项
3. 加:点击加,购物车中该商品数量增加1
4. 减:点击减,购物车中该商品数量减少1,并且当减到1的时候,提示不能再减
一、鼠标的移入与移出:
在鼠标未移入的时候,页面效果是这样的:
在页面的右侧主要有两块:
1.购物车图标
2.鼠标移入购物车图标后,右侧部分左滑,显示购物车中的 商品,也就是下图这个样子:
在这里首先解释CSS部分,理解之后,JQuery部分就好理解了。
CSS代码如下:
.sc_right{
/* 右侧部分绝对定位 并设定宽为270px*/
position: absolute;
width: 270px;
height: 100%;
/* 在设置绝对定位的前提下, 距离右侧-270px 也就是右侧这一块全部向右偏移,这个效果做出来是:将右侧270px给隐藏起来*/
right: -270px;
/* 设置一个左边框 在这里是红色线的效果是给sc_right添加一个左边框,而不是给购物车图片一个右边框 */
border-left: 1px solid red;
}
.sc_pic{
width: 50px;
height: 50px;
background-color: #666;
/* 购物车图片设置绝对定位,在没有设置偏移的时候,默认是在.sc_right块(也就是右侧块)的左上角的,设置top为50%,则购物车图片就会放在中间高度,而设置左边偏移是为了 购物车部分在隐藏的时候,还能看到购物车图片 */
position: absolute;
left: -51px;
top: 50%;
/* 因为此处和后面的购物车数量都使用的绝对定位,在这里使用z-index可以避免无法显示或者显示不完全的情况
其中,z-index后面的值越大,越先显示 */
z-index: 1;
}
.sc_pic img{
width: 60%;
height: 60%;
position: relative;
top: 10px;
left: 8px;
}
.sc_num{
position: absolute;
padding: 2px 6px;
top: -5px;
right: 1px;
background-color: red;
border-radius: 50%;
z-index: 2;
}
JQuery代码如下:
1.开始时右侧宽度为270px,但是此时的效果是右侧购物车中的数据是隐藏着的,当鼠标移入的时候,距离右边变为0 ,相当于右偏移没有了,就可以显示全部了,移出的时候仍变回原来-270即可。
2.添加stop是为了阻止上次的动画效果
$(".sc_right").mouseover(function(){
$(this).stop(true).animate({
right : 0
},500)
})
$(".sc_right").mouseout(function(){
$(this).stop(true).animate({
right:-270
})
})
二、点击删除键
因为删除键是后来添加的节点,所以需要通过事件委托的方式进行添加点击事件
需要删除的有:
1.删除页面上存放这个商品的li标签;
2.删除cookie中的数据,通过当前要删除的商品的id进行删除
大致步骤:
1.找到当前点击商品所在的li标签,删除,并获取这个标签的id(商品id),
2.将cookie中的数据取出来,转化为数组类型,通过for循环,找到与当前 1 中获取的id一致的商品,通过数组的splice方法将这个商品的信息删除掉,然后跳出循环
3.删除之后,判断cookie数组是否为空,如果为空,则将cookie直接设为空,如果不为空 将数组类型的数据转换为JSON型存放放到cookie中,
4,调用sc_num()函数,重新计算购物车中的商品数量
具体JQuery代码如下:
// 通过事件委托给删除按钮添加点击事件
$(".sc_right ul").on("click",".sc_delBtn",function(){
/*
页面上存在的节点删除
cookie中存储删除数据,必须通过当前所在商品id删除
*/
// 找到距离里当前最近的li节点
var id = $(this).closest('li').remove().attr("id");
// console.log(id);
var cookieStr = $.cookie("goods");
var cookieArr = JSON.parse(cookieStr);
for(var i = 0; i< cookieArr.length; i++){
if(cookieArr[i].id == id){
// 通过数组的splice方法将i这个下标的元素删除掉,1代表删除一个
cookieArr.splice(i,1);
// 删除完一个,跳出循环
break;
}
}
// 判断数组是否为空
if(!cookieArr.length){
$.cookie("goods",null)
}else{
$.cookie("goods",JSON.stringify(cookieArr),
{expires: 7})
}
sc_num();
})
三、点击加减:
大致步骤:
1. 获取当前点击商品的id,
2. 通过for循环,找到与当前id一致的商品的信息,
3.判断当前点击的button标签的innerHTML的内容是加还是减,
4,是 + :则只需要将这个商品的数量加一即可
5,是 - : 判断商品数量是否为1,如果为1,则进行提示,如果 不为1,则,直接进行数据路减一
6. 加减完毕之后,需要重新设置页面上的商品数量,并更新cookie中的商品信息
7.跳出循环
8.循环结束之后,重新计算购物车中商品的数量,(只需调用一下sc_num()即可)
JQuery代码如下:
// 通过事件委托去给加减添加点击事件
$(".sc_right ul").on("click","button",function(){
// 获取商品id
var id = $(this).closest("li").attr("id");
// console.log(id);
// 找到修改的商品
var cookieStr = $.cookie("goods");
var cookieArr = JSON.parse(cookieStr);
for( var i = 0; i< cookieArr.length; i++){
if(id == cookieArr[i].id){
if(this.innerHTML== "+"){
cookieArr[i].num++;
}else{
if(cookieArr[i].num == 1){
alert("数量已为1,不能再减");
}else{
cookieArr[i].num--;
}
}
// 设置页面上新的商品数
// 重新设置商品新的数量
$(this).prevAll(".sc_goodsNum").html("商品数量:" +cookieArr[i].num);
$.cookie("goods",JSON.stringify(cookieArr),{
expires: 7
})
break;
}
}
sc_num();
})
四、完整代码:
本文的代码较(一)来说,有所改动,故在此重新放一下全部的代码!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../jquery-1.10.1.min.js"></script>
<script src="jquery.cookie.js"></script>
<script>
$(function(){
sc_num();
sc_msg();
$.ajax({
url:"data.json",
dataType:"JSON",
success:function(result){
for(var i = 0 ;i< result.length;i++){
var node = $(`<li class="goods_item">
<div class="goods_pic">
<img src="${result[i].img}" alt=""/>
</div>
<div class="goods_title">【京东超市】奥利奥软点小草莓</div>
<div class="sc">
<div id="${result[i].id}" class="sc_btn">加入购物车</div>
</div>
</li>`)
node.appendTo($(".goods_box ul"))
}
}
})
$(".goods_box ul").on("click",".sc_btn",function(){
// alert(1)
var id = this.id;
// first是否是空 是的话返回true,不是否会false
var first = $.cookie("goods") == null?true:false;
if(first){
// 如果first为空,则将当前点击的商品的id和数量1存入cookie中,并保存7天
var arr = [{id:id,num:1}];
$.cookie("goods",JSON.stringify(arr),{
expires:7
})
}else{
// 如果不为空,判断是否是第一次加入购物车
var cookieStr = $.cookie("goods")
var cookieArr = JSON.parse(cookieStr);
var same = false;//假设没有添加过该商品
for(var i = 0;i< cookieArr.length; i++){
// 如果已经加入购物车,则数量加一
if(cookieArr[i].id == id){
same = true;
cookieArr[i].num ++;
break;
}
}
if(!same){
cookieArr.push({id:id,num:1});
}
$.cookie("goods",JSON.stringify(cookieArr),{
expires: 7
})
// alert($.cookie("goods"))
}
sc_num();
sc_msg();
})
/* 刚开始是线在购物车图标左侧,开始时右侧宽度为20px,但是此时的效果是右侧购物车中的数据是隐藏着的,当鼠标移入的时候,距离右边变为0 ,相当于右偏移没有了,就可以显示全部了,移出的时候仍变回原来-270即可。
添加stop是为了阻止上次的动画效果*/
$(".sc_right").mouseover(function(){
$(this).stop(true).animate({
right : 0
},500)
})
$(".sc_right").mouseout(function(){
$(this).stop(true).animate({
right:-270
})
})
function sc_num(){
var cookieStr = $.cookie("goods");
if(cookieStr){
var cookieArr = JSON.parse(cookieStr);
var sum = 0;
for(var i =0 ; i< cookieArr.length ; i++){
sum +=cookieArr[i].num;
}
$(".sc_right .sc_num").html(sum);
}else{
$(".sc_right .sc_num").html(0);
}
}
// 购物车中的商品显示
/*
先获取data中的数据,然后获取cookie中的数据,然后将data与cookie中的数据id进行比对,
*/
function sc_msg(){
// 清空上一次加载数据
$(".sc_right ul").html("");
// 清空当前节点的所有的子节点
// $(".sc_right ul").empty();
$.ajax({
url:"data.json",
dataType:"JSON",
success:function(res){
var cookieStr = $.cookie("goods");
var newArr = [] ;
if(cookieStr){
var cookieArr = JSON.parse(cookieStr);
for(var i = 0; i< res.length ; i++){
for(var j = 0; j< cookieArr.length; j ++){
if(res[i].id == cookieArr[j].id){
res[i].num = cookieArr[j].num;
newArr.push(res[i])
}
}
}
console.log(newArr);
for(var i = 0 ; i<newArr.length; i ++){
var node = $(`<li id="${newArr[i].id}">
<div class="sc_goodsPic">
<img src="${newArr[i].img}" alt="">
</div>
<div class="sc_goodsTitle">
<p>这是商品曲奇饼干</p>
</div>
<div class="sc_goodsBtn">购买</div>
<div class="sc_delBtn">删除</div>
<div class="sc_goodsNum">商品数量:${newArr[i].num}</div>
<button>+</button>
<button>-</button>
</li>`);
node.appendTo($(".sc_right ul"));
}
}
}
})
}
$(".clearSc").click(function(){
$.cookie("goods",null);
sc_num();
sc_msg();
})
// 通过事件委托给删除按钮添加点击事件
$(".sc_right ul").on("click",".sc_delBtn",function(){
/*
页面上存在的节点删除
cookie中存储删除数据,必须通过当前所在商品id删除
*/
// 找到距离里当前最近的li节点
var id = $(this).closest('li').remove().attr("id");
// console.log(id);
var cookieStr = $.cookie("goods");
var cookieArr = JSON.parse(cookieStr);
for(var i = 0; i< cookieArr.length; i++){
if(cookieArr[i].id == id){
// 通过数组的splice方法将i这个下标的元素删除掉,1代表删除一个
cookieArr.splice(i,1);
// 删除完一个,跳出循环
break;
}
}
// 判断数组是否为空
if(!cookieArr.length){
$.cookie("goods",null)
}else{
$.cookie("goods",JSON.stringify(cookieArr),
{expires: 7})
}
sc_num();
})
// 通过事件委托去给加减添加点击事件
$(".sc_right ul").on("click","button",function(){
// 获取商品id
var id = $(this).closest("li").attr("id");
// console.log(id);
// 找到修改的商品
var cookieStr = $.cookie("goods");
var cookieArr = JSON.parse(cookieStr);
for( var i = 0; i< cookieArr.length; i++){
if(id == cookieArr[i].id){
if(this.innerHTML== "+"){
cookieArr[i].num++;
}else{
if(cookieArr[i].num == 1){
alert("数量已为1,不能再减");
}else{
cookieArr[i].num--;
}
}
// 设置页面上新的商品数
// 重新设置商品新的数量
$(this).prevAll(".sc_goodsNum").html("商品数量:" +cookieArr[i].num);
$.cookie("goods",JSON.stringify(cookieArr),{
expires: 7
})
break;
}
}
sc_num();
})
})
</script>
<style>
*{
margin: 0;
padding: 0;
}
li{
list-style: none;
}
.goods_box ul{
width: 1100px;
margin: 20px auto 0;
}
/* .goods_box ul:after{
content: "";
display: block;
clear: both;
} */
.goods_item{
float: left;
padding: 10px 6px;
border-right: 1px solid red;
margin-bottom: 30px;
}
.goods_pic{
width: 160px;
height: 160px;
padding: 20px 15px;
margin: 0 auto;
}
.goods_pic img{
width: 100%;
height: 100%;
}
.goods_title{
font-size: 12px;
color: #999;
display: block;
padding: 13px 0 7px;
text-align: left;
max-width: 100%;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.sc_btn{
/* position: absolute; */
width: 120px;
height: 30px;
background-color: red;
color: white;
font-size: 16px;
font-weight: bold;
line-height: 30px;
text-align: center;
margin: 0 auto;
border-radius: 5px;
}
.sc_right{
/* 右侧部分绝对定位 并设定宽为270px*/
position: absolute;
width: 270px;
height: 100%;
/* 在设置绝对定位的前提下, 距离右侧-270px也就是,这个效果做出来是:将右侧270px给隐藏起来*/
right: -270px;
/* 设置一个左边框 */
border-left: 1px solid red;
}
.sc_pic{
width: 50px;
height: 50px;
background-color: #666;
/* 购物车图片设置绝对定位,在没有设置偏移的时候,默认是在.sc_right块(也就是右侧块)的左上角的,设置top为50%,则购物车图片就会放在中间高度,而设置左边偏移是为了 购物车部分在隐藏的时候,还能看到购物车图片 */
position: absolute;
left: -51px;
top: 50%;
/* 因为此处和后面的购物车数量都使用的绝对定位,在这里使用z-index可以避免无法显示或者显示不完全的情况
其中,z-index后面的值越大,越先显示 */
z-index: 1;
}
.sc_pic img{
width: 60%;
height: 60%;
position: relative;
top: 10px;
left: 8px;
}
.sc_num{
position: absolute;
padding: 2px 6px;
top: -5px;
right: 1px;
background-color: red;
border-radius: 50%;
z-index: 2;
}
.sc_goodsPic{
width: 80px;
height: 80px;
border: 1px solid #999;
float: left;
}
.sc_goodsPic img{
width: 100%;
height: 100%;
}
.sc_goodsTitle{
line-height: 40px;
color: #999;
margin-left: 20px;
float: left;
}
.sc_goodsBtn{
font-size: 14px;
background: #fc1934;
color: #fff;
text-align: center;
float: left;
line-height: 30px;
width: 35px;
height: 30px;
margin-left: 20px;
cursor: pointer;
}
.sc_delBtn{
font-size: 14px;
background: blue;
color: #fff;
text-align: center;
float: left;
line-height: 30px;
width: 35px;
height: 30px;
/* margin-left: 20px; */
cursor: pointer;
}
.sc_goodsNum{
float: left;
line-height: 30px;
font-size: 10px;
margin-left: 5px;
}
.sc_right li{
height: 100px;
}
.sc_right li button{
width: 20px;
height: 20px;
background-color: orange;
color: black;
margin-top: 10px;
}
</style>
</head>
<body>
<button class="clearSc">清空购物车</button>
<!-- <div class="clearSc">清空购物车</div> -->
<!-- 商品部分 -->
<div class="goods_box">
<ul>
</ul>
</div>
<!-- 购物车部分 -->
<div class="sc_right">
<div class="sc_pic">
<img src="cart.png" alt="">
<div class="sc_num">
0
</div>
</div>
<ul></ul>
</div>
</body>
</html>