购买页面
<!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" }]