购买页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
#cont{1000px;overflow: auto;margin: 0 auto;border: solid 1px black;}
#cont .box{ 250px;border: solid 1px black;box-sizing: border-box;float: left;text-align: center;}
.box p{line-height: 20px;height:40px;overflow: hidden;margin: 6px 0}
.box img{200px;height:200px;}
</style>
</head>
<body>
<h2>这是商品列表<a href="car.html">去结算</a></h2>
<div id="cont">
<p>不好意思,商品卖完了</p>
</div>
</body>
<script src="js/ajax.js"></script>
<script src="js/cookie.js"></script>
<script>
// 一、渲染页面
class Shop{
constructor(){
this.url = "http://localhost/1908/shopping/data/goods.json";
this.cont = document.getElementById("cont");
this.load();
this.addEvent();
}
load(){
ajax({
url:this.url,
success:res=>{
this.res = JSON.parse(res);
// console.log(this.res)
this.display()
}
})
}
display(){
var str = "";
for(var i=0;i<this.res.length;i++){
str += `<div class="box" index="${this.res[i].goodsId}">
<img src="${this.res[i].img}" alt="">
<p>${this.res[i].name}</p>
<span>${this.res[i].price}</span>
<input type="button" value="加入购物车" class="add">
</div>`
}
this.cont.innerHTML = str;
}
addEvent(){
var that = this;
// 二、点击加入
this.cont.addEventListener("click",function(eve){
var e = eve || window.event;
var target = e.target || e.srcElement;
if(target.className == "add"){
// 1.点击时找到当前点击商品的货号
that.id = target.parentNode.getAttribute("index");
// 2.准备存cookie
that.setCookie()
}
})
}
setCookie(){
// 三、存储数据(cookie)
// 商品id,商品数量
// 多个商品
// 数据格式:对象为基础,一个对象存储一个商品;多个商品,多个对象,放在一个数组中
// [{id:"adasd",num:12},{id:"132a",num:6},{},{},{}....]
this.goods = getCookie("goods") ? JSON.parse(getCookie("goods")) : [];//第一次执行getcookie获取不到,所以为空;这点最难理解。点击按钮的时候肯定是想在原先的基础num上加1,但是有可能你是第一次点击,这时候你就要往里面写cookie,而不能在原先的基础上改变cookie了。
//this.goods中只有num和id;
// 3.存之前,判断是第一次还是非第一次
if(this.goods.length < 1){ //长度小于1,说明肯定是第一次存咯。
this.goods.push({
id:this.id,//id就是你点击的那一个商品的goodsId;
num:1//num为1
})
}
else{//虽然页面不是第一次点击,但是可能这个商品是第一次点击,所以依然进行判断
var onoff = 1;
for(var i=0;i<this.goods.length;i++){ //遍历整个cookie,判断点击的商品id在之前有没有点击过。
if(this.goods[i].id === this.id){
this.goods[i].num++;// 存在,增加数量
onoff = 0;// 同时修改状态,防止它继续往下执行
}
}
// 判断状态,不存在
if(onoff == 1){ //这个商品是第一次点击,与第一次点击商品操作相同
// 直接增加
this.goods.push({
id:this.id,//这个this.id在构造函数时获取到的;
num:1
})
}
}
// 4.经过第三步对数据的处理,可以将数据再设置回cookie了
setCookie("goods",JSON.stringify(this.goods))//if执行完之后执行这个;
console.log(this.goods)
console.log(JSON.stringify(this.goods))
}
}
new Shop();
</script>
</html>
购物车页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>这是购物车页面<a href="shop.html">继续购物</a></h2>
<table border="1" width="900" align="center">
<thead>
<tr>
<th>图片</th>
<th>名字</th>
<th>价格</th>
<th>数量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!-- <tr>
<td><img src=""></td>
<td>Data</td>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr> -->
</tbody>
</table>
</body>
<script src="js/cookie.js"></script>
<script src="js/ajax.js"></script>
<script>
//更改设置cookie都是用的是json样式
class Car{
constructor(){
this.url="http://localhost/shopping/data/goods.json";
this.tbody = document.querySelector("tbody");
this.load();
this.addEvent();
}
addEvent(){
var that=this;
this.tbody.addEventListener("click",function(eve){
var e = eve || window.event;
var target = e.target || e.srcElement;
if(target.tagName == "SPAN"){
// 8.保存删除时的商品id
that.id = target.parentNode.parentNode.getAttribute("index");
// console.log(that.id)
// 9.开始删除:删除DOM,修改cookie
target.parentNode.parentNode.remove();
that.removeCookie();
}
})
this.tbody.addEventListener("input",function(eve){
var e = eve || window.event;
var target = e.target || e.srcElement;
if(target.type == "number"){
// 11.保存修改商品的id
that.id = target.parentNode.parentNode.getAttribute("index");
// 保存修改商品的数量
that.val = target.value;//自己设的val等于 target.value(是由自己输得)
// 修改cookie
that.updateCookie()
}
})
}
updateCookie(){ //当手动使num的数量增加时,仅仅是在页面上显示增加了,一刷新就恢复原样了。所以要更新cookie中的id。cookie中的id等于自己点击的那个按钮所在商品栏的id;
// 准备保存出数据的索引
var i = 0;
// 遍历数组,找到符合条件的数据
var onoff = this.goods.some((val,index)=>{//这里的val是cookie中的json的每一个对象。
i = index;
return val.id == this.id;//val.id是cookie中的id
})
if(onoff){
// 找到符合的数据之后,更新数组中的数据
this.goods[i].num = this.val;//这里的this.val是输入框总的值
}
// 将数组再设置回cookie
setCookie("goods",JSON.stringify(this.goods)) //更改设置cookie都是用的是json样式
}
removeCookie(){
var i=0;
var onoff=this.goods.some((val,index)=>{ //val是数组对象中中,每一个对象。
i=index;//每次将传达的索引存出来。就是所点击的那个id在cookie数组中拍的那个位置。
return val.id==this.id;//返回val的id是否等当前点击的id;如果相等返回true,同时index停止往前走。
})
if(onoff){ //找到相同的了。
this.goods.splice(i,1)
}
setCookie("goods",JSON.stringify(this.goods)) //更改了原来的cookie;
}
load(){ //找ajax中的id
var that=this;
ajax({
url:this.url,
success:function (res) {
that.res=JSON.parse(res)//要在display中同时拿到this.res.id和this.goodsId;若果在ajax中display那就拿不到this.goods.id,若果在getCookie中执行那就拿不到this.res.id。做好的办法是用promise来是他们都执行完在执行diplay,但是目前情况没学。所以我们可以在ajax执行完执行getCookie,然后再getCookie中执行display;
that.getCookie();
}
})
}
getCookie(){//找cookie中的id
this.goods=getCookie("goods")?JSON.parse(getCookie("goods")):[];
this.display();
}
display(){
var str=""
for(var i=0;i<this.goods.length;i++){
for(var j=0;j<this.goods.length;j++){
if(this.res[i].goodsId==this.goods[j].id){ //ajax中的数据与cookie中的数据相同时;渲染页面
str += `<tr index="${this.goods[j].id}">
<td><img src="${this.res[i].img}"></td>
<td>${this.res[i].name}</td>
<td>${this.res[i].price}</td>
<td><input type="number" value="${this.goods[j].num}" min=1 /></td>
<td><span>删除</span></td>
</tr>`;
}
}
}
this.tbody.innerHTML=str
}
}
new Car;
</script>
</html>
ajax.js
function ajax(options){ // 1.处理默认参数 var {type,url,success,error,data,timeout} = options; type = type || "get"; data = data || {}; timeout = timeout || 2000; // 2.解析要发送的数据 var str = ""; for(var i in data){ str += `${i}=${data[i]}&`; } // 3.根据方式,决定是否处理url if(type == "get"){ var d = new Date(); url = url + "?" + str + "__qft=" + d.getTime(); } // 4.开启ajax var xhr = new XMLHttpRequest(); // 注意:open中的方式 xhr.open(type,url,true); xhr.onreadystatechange = function(){ if(xhr.readyState == 4 && xhr.status == 200){ // 5.执行成功之前,先判断是否传入 success && success(xhr.responseText); // 成功之后,不应有失败 error = null; }else if(xhr.readyState == 4 && xhr.status != 200){ // 6.执行失败之前,先判断是否传入 error && error(xhr.status); // 失败之后,不应有成功 success = null; // 且失败不应多次执行 error = null; } } // 7.如果请求超时,执行失败 setTimeout(() => { error && error("timeout"); // 失败之后,不应有成功 success = null; }, timeout); // 8.最后根据type的方式,决定send的发送内容和格式 if(type == "post"){ xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xhr.send(str) }else{ xhr.send() } }
cookie.js
function setCookie(key,val,options){ options = options || {}; var path = ""; if(options.path){ path = ";path=" + options.path; } var expires = ""; if(options.expires){ var d = new Date(); d.setDate(d.getDate()+options.expires); expires = ";expires=" + d; } document.cookie = key + "="+ val + path + expires; } function removeCookie(key,options){ options = options || {}; options.expires = -1; setCookie(key,132,options); } function getCookie(key){ var arr = document.cookie.split("; "); for(var i=0;i<arr.length;i++){ if(arr[i].split("=")[0] === key){ return arr[i].split("=")[1]; } } return ""; }
所需要的Json数据
[{ "img":"https://img10.360buyimg.com/n7/jfs/t5617/321/1137763311/121847/b9326254/5923eb44Ndae8df59.jpg.webp", "name":"微软(Microsoft)Surface Pro 二合一平板电脑 12.3英寸(Intel Core i5 8G内存 256G存储 )", "price":"9888.00", "goodsId":"ajdaj" },{ "img":"https://img13.360buyimg.com/n7/jfs/t17425/6/1117130719/77250/b4afe949/5abb0fc0Nb0fd7afd.jpg.webp", "name":"Apple iPad 平板电脑 2018年新款9.7英寸(128G WLAN版/A10 芯片/Touch ID MRJP2CH/A)金色", "price":"5999.00", "goodsId":"254654" },{ "img":"https://img14.360buyimg.com/n2/jfs/t22945/291/2044515279/67669/7a4a50e/5b713f0eN0caa8e0b.jpg.webp", "name":"微软(Microsoft)Surface Go 二合一平板电脑 10英寸(英特尔 奔腾 金牌处理器4415Y 8G内存 128G存储)", "price":"3738.00", "goodsId":"qwqwe" },{ "img":"https://img11.360buyimg.com/n2/jfs/t5935/195/2108753717/176060/c849dcb6/593a49a3Nf9c2a052.jpg.webp", "name":"Apple MacBook Air 13.3英寸笔记本电脑 银色(2017新款Core i5 处理器/8GB内存/128GB闪存 MQD32CH/A)", "price":"5999.00", "goodsId":"13ads" }]