购物车究极

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="css/index.css">
</head>
<body>
    <header>网页头部区域</header>
    <main>
        <ul></ul>
    </main>
    <a href="html/cart.html">
        <div class="count">
            商品共<span>0</span></div>
    </a>
    <!--json数据格式不能直接使用js文件引用,必须通过ajax请求-->
    <script src="js/ajax.js"></script>
    <script src="js/index.js"></script>
</body>
</html>


index.js
class List{
    constructor() {
        //获取元素
        this.container = document.querySelector('ul')
        this.span = document.querySelector('span')
        this.init()
    }
    init() {
        this.request()
        //注意点:data数据是发送请求获取到的,在初始化的时候直接调用代码,异步代码是没有返回结果的所以是undefined
        // this.cart()
        this.count()
    }
    request() {
        pAjax({url: 'data/goods.json'})
        .then((res)=>{
            let data = JSON.parse(res)
            data = data.slice(0, 60)
            this.render(data)
            this.cart(data)
        })
    }
    render(data) {
        data.forEach((item) => {
            //html/details.html?id=${item.goods_id}在查询字符串后面进行参数拼接,可以让网页跳转的时候把需要的参数携带到另一个网页
            this.container.innerHTML += `
                     <li>
                       <a href="html/details.html?id=${item.goods_id}" style="text-decoration:none; color:black;">
                        <div class="pic">
                            <img src="${item.img_small_logo}">
                        </div>
                        <p class="title hide">${item.title}</p>
                        <p class="price">${item.price}</p>
                        </a>
                        <button data-id=${item.goods_id}>加入购物车</button>
                    </li>
                `
        })
    }
    cart(data){
        //做事件委派
        this.container.addEventListener('click', (e) => {
            e = e || window.event
            let target = e.target || e.srcElement
            //判断是否点击的是按钮
            if (target.nodeName == 'BUTTON') {
                //获取到每一个按钮的id
                let id = target.dataset.id - 0
                //当咱们点击对应的按钮的时候,获取到相应那条数据
                let goods = data.find((item) => { return item.goods_id == id })
                //先获取下购物车里面有没有数据,如果没有数据让它返回一个空数组
                let list = JSON.parse(localStorage.getItem('cart')) || []
                //判断里面有没有数据
                if (!list.length) {
                    //没有数据,如果能进到这个地方说明就是没有数据的
                    //没有数据,应该先把数据添加进数组,并让商品数量赋值为1
                    list.push(goods)
                    goods.cart_number = 1
                } else {
                    //如果有数据,先判断下数组里面有没有这条数据,防止重复存在
                    let res = list.some((item) => { return item.goods_id == id })
                    //如果数据相同,应该找到相同的数据让其商品数量自增+1
                    if (res) {
                        let index = list.findIndex((item) => { return item.goods_id == id })
                        list[index].cart_number++
                    } else {
                        //没有相同的,就把数据添加进数组
                        list.push(goods)
                        goods.cart_number = 1
                    }
                }
                //把对应的数据应该存储进购物车里面
                localStorage.setItem('cart', JSON.stringify(list))
                //当咱们点击按钮的时候,让商品数量进行变化
                this.count()
            }
        }, false)
    }
    count() {
        //先从购物车里面把数据提取出来
        let list = JSON.parse(localStorage.getItem('cart')) || []
        let num = 0
        //遍历进行数量增加
        list.forEach((item) => {
            num += item.cart_number
        })
        //给span标记进行赋值操作
        this.span.innerHTML = num
    }
}
new List()
cart.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="../css/cart.css">
</head>

<body>
    <div class="cartTable">
        <table>
            <thead>
                <tr>
                    <th>全选</th>
                    <th>商品</th>
                    <th>单价</th>
                    <th>数量</th>
                    <th>小计</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody></tbody>
        </table>

        <div class="footer">
            <div class="left">
                <input type="checkbox" value="" class="selectAll" />
                <span class="dlAll">删除</span>
            </div>
            <div class="rirght">
                <div class="allNum">已选商品<b class="totalNum">0</b></div>
                <div class="allCount">合计 ¥<b class="money">0</b></div>
                <!---当咱们点击结算标记的时候,使用存储方式在本地进行保存,当跳到支付页面的时候再获取出来渲染页面-->
                <a href="total.html">
                    <div class="calc">结算</div>
                </a>
            </div>
           
            
    </div>
        <script src="../js/cart.js"></script>
</body>

</html>

cart.js
class Cart{
    constructor() {
        //获取元素
        this.cartTable = document.querySelector('.cartTable')
        this.tbody = document.querySelector('tbody')
        this.totalNum = document.querySelector('.totalNum')
        this.money = document.querySelector('.money')
        this.selectAll = document.querySelector('.selectAll')
        //获取数据
        this.data = JSON.parse(localStorage.getItem('cart')) || []
        //调用init方法
        this.init()
    }
    init(){
        this.render()
        this.bindHtml()
        this.total()
    }
    //根据数据渲染页面
    render() {
        this.tbody.innerHTML = ''
        //思考:列表页面如果添加了商品,购物车里面就有数据,如果没有添加就没有数据
        if (!this.data.length) {
            //如果没有数据就进入这里,给用户一个提示
            this.tbody.innerHTML = `
               <tr height="100">
                 <td colspan="6">  
                    <h1>您的购物车空空如也! 赶紧去购物吧<a href="../_index.html">Go</a></h1>
                 </td>
               </tr>
            `
        } else {
            this.data.forEach(item => {
                this.tbody.innerHTML += `
                <tr>
                    <td><input type="checkbox" value="" class="select" data-id="${item.goods_id}" ${item.is_select && "checked"}/></td>
                    <td>
                        <img src="${item.img_small_logo}">
                        <span class="hide">${item.title}</span>
                    </td>
                    <td><span class="price">${item.price}</span></td>
                    <td>
                        <span class="sub" data-id="${item.goods_id}">-</span>
                        <input type="text" value="${item.cart_number}" class="txt" data-id="${item.goods_id}" />
                        <span class="add" data-id="${item.goods_id}">+</span>
                    </td>
                    <td><span class="subTotal">${item.cart_number * item.price}</span></td>
                    <td><span class="del" data-id="${item.goods_id}">删除</span></td>
                </tr>
                `
            })
        }
        //数据持久化
        localStorage.setItem('cart', JSON.stringify(this.data))
    }
    //给html绑定各种事件
    bindHtml() {
        //做事件委派
        this.cartTable.addEventListener('click', (e) => {
            //事件对象兼容写法
            e = e || window.event
            //事件(目标事件)源兼容写法
            let target = e.target || e.srcElement
            //做全选功能
            if (target.className == 'selectAll') {
                console.log(this.data)
                //获取全选按钮的状态
                let type = target.checked
                //当咱们点击全选按钮的时候,让所有的单选按钮选中或未选中
                //思路:使用数据驱动页面,修改的是数组
                this.data.forEach(item => {
                    item.is_select = type
                })
                //当咱们把数据修改了应该重新渲染页面
                this.render()
                this.total()
            }
            //单选功能
            //注意点:在服务器环境下,很多的数据会进行缓存,所以当有时候有些数据会从浏览器缓存里面获取,会导致代码出错
            if (target.className == 'select') {
                let id = target.dataset.id - 0
                let goods = this.data.find(item => { return item.goods_id == id })
                //改变选中状态
                goods.is_select = !goods.is_select
                //渲染页面
                this.render()
                this.total()
            }
            //点击数量增加
            if (target.className == 'add') {
                let id = target.dataset.id - 0
                let goods = this.data.find(item => { return item.goods_id == id })
                if (goods.cart_number == goods.goods_number) {
                    alert('亲,只能买这么多!')
                    return false
                }
                goods.cart_number ++
                //渲染页面
                this.render()
                this.total()
            }
            //点击数量减少
            if (target.className == 'sub') {
                let id = target.dataset.id - 0
                let goods = this.data.find(item => { return item.goods_id == id })
                if (goods.cart_number == 1) {
                    return false
                }
                goods.cart_number--
                //渲染页面
                this.render()
                this.total()
            }
            //删除操作
            if (target.className == 'del') {
                let id = target.dataset.id - 0
                //注意点:返回的是在数组里面的位置
                let index = this.data.findIndex(item => { return item.goods_id == id })
                this.data.splice(index, 1)
                //如果数组是空的,把全选框的状态改为false
                if (!this.data.length) {
                    this.selectAll.checked = false
                }
                //渲染页面
                this.render()
                this.total()
            }
            //清空购物车
            if (target.className == 'dlAll') {
                //如果都是true的状态说明都是选中的,把你给过滤掉,只剩下状态是false的重新赋值
                let res = this.data.filter(item => { return item.is_select == false })
                this.data = res
                //如果数组是空的,把全选框的状态改为false
                if (!this.data.length) {
                    this.selectAll.checked = false
                }
                //渲染页面
                this.render()
                this.total()
            }
        }, false)
    }
    //计算总价和数量
    total() {
        //使用两个变量保存总的数量和总价格
        let num = 0
        let money = 0
        //遍历数组
        this.data.forEach(item => {
            //当单选按钮是选中状态的时候应该计算
            if (item.is_select == true) {
                num += item.cart_number
                money += item.cart_number * item.price
                //当咱们单选框是选中的状态进行判断全选框是否选中
                let res = this.data.every(item => { return item.is_select == true })
                if (res) {
                    this.selectAll.checked = true
                } else {
                    this.selectAll.checked = false
                }
            }
        })
        //进行赋值操作
        this.totalNum.innerHTML = num
        this.money.innerHTML = money
    }
}
new Cart()
details.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="../css/details.css">
</head>
<body>
    <header>这是网页头部区域</header>
    <main>
        <div class="con">
            <div class="left">
                <div class="pic">
                    <img src="" alt="" width="300" height="300">
                </div>
                <ul>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                </ul>
            </div>
            <div class="right"></div>
        </div>
        <div class="dtl">

        </div>
    </main>
    <script src="../js/ajax.js"></script>
    <script src="../js/details.js"></script>
</body>
</html>

details.js
/*
    详情页面逻辑
    + 当咱们在商品列表页面点击某个商品的时候,通过查询字符串的形式把商品id携带到详情页面
    + 先获取到商品id
    + 发送ajax请求
      => 把获取到的数据和id进行对比
      => 把相应的数据拿出来渲染页面
*/
class Details{
    constructor() {
        //获取元素
        this.pic = document.querySelector('.pic>img')
        this.dtl = document.querySelector('.dtl')
        this.init()
    }
    init() {
        this.request()
    }
    //查询字符串处理
    queryStr(name) {
        //?id=2&username=zhangsan
        let str = location.search
        let obj = {}
        let arr = str.split('?')[1]
        arr = arr.split('&')
        arr.forEach(item => {
            let newArr = item.split('=')
            obj[newArr[0]] = newArr[1]
        })
        return obj[name]
    }
    //发送请求
    request() {
        let id = this.queryStr('id')
        pAjax({ url: '../data/goods.json' })
            .then(res => {
                let data = JSON.parse(res)
                data = data.slice(0, 60)
                data.forEach(item => {
                    if (item.goods_id == id) {
                        this.render(item)
                    }
                })
        })
    }
    //渲染页面
    render(data) {
        //img_small_logo
        //goods_introduce
        // console.log(data)
        this.pic.src = data.img_small_logo
        this.dtl.innerHTML = data.goods_introduce
    }
}
new Details()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值