zoukankan      html  css  js  c++  java
  • 购物车案例详解。利用cookie

    购买页面

    <!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"
    }]
  • 相关阅读:
    Android最流行的网络框架
    linux知识库
    linux tail命令使用
    Android系列之Fragment(二)Fragment的生命周期和返回栈
    viewpager中fragment的生命周期管理
    fragment和fragmentactivity解析
    Android之Activity,Fragment生命周期探知
    Fragment生命周期
    基础总结篇之四:Service完全解析
    Activity的task相关
  • 原文地址:https://www.cnblogs.com/hy96/p/11550789.html
Copyright © 2011-2022 走看看