用JS实现购物车

一、原理
将商品加入购物车,实际上是将所选商品信息加入购物车的表里,我们所建的页面表是读取数据库里购物车的数据表,里面加了谁,就将其对应的数据获取出来放到建的页面表中

二、功能实现:

  • “全选”复选框:
  1. 点“全选”前的复选框,将商品全部选择;再点一次,则取消选择
  2. 将商品全选后,“全选”前的复选框需打勾;只要去掉一个商品,“全选”前复选框的勾则被取消
  • 购物车数量:点”-“或”+“按钮,对所选商品数量进行增减
  • 结算金额(单价*数量):其中的单价可自定义一个属性(即data-price),获取当前类名称的元素对象,拿索引对索引,取其里面的值;数量为功能2中的val;根据索引对索引,金额的文本内容即为单价与数量相乘
  • 将勾选商品的金额放到下面的“合计”中:
  1. 设置金额的属性(即data-totle),其值为后面每次计算的总值赋给它(即totle[this,index]);
  2. 将1.写为一个金额的计算方法,传入形参(index,value),在购物车数量的增减事件中调用,并传入实参(this.index,val);
  3. 合计加总金额时,需判断商品信息前的复选框是否被选中,选中则加,不选中则不加:
    (1)添加一个判断商品信息前的复选框是否打勾的方法(即ischoose());
    (2)将ischoose()方法在购物车数量的增和减事件、全选复选框的点击事件、全选复选框的点击事件中使用;
  4. 已选商品的数量:在合计时,将所选商品的数量相加后的值给其赋之

三、代码块
html代码:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        table{
            border-collapse: collapse;  //单元格合并
            width: 1000px;
            margin: 0 auto;
            border: 1px solid silver;
        }
        .title{
            font-size: 14px;
        }
        .face{
            width: 80px;
        }
        .word{
            width: 200px;
            font-size: 12px;
            color: red;
            display: inline-block;
            text-decoration: none;
            margin-left: 10px;
        }
        td{
            padding: 10px 0;
            min-width: 65px;
        }
        .price{
            font-weight: bold;
            color: black;
        }
        .totle{
            font-weight: bold;
            color: red;
        }
        tr{
            border: 1px solid #d8d8d8;
            background-color: #f6f6f6;
        }
        .btn button{
            width: 30px;
            height: 30px;
            outline: none;
            border-style: none;
            background-color: #e0e0e0;
        }
        .btn input{
            width: 30px;
            height: 30px;
            text-align: center;
        }
    </style>
</head>
<body>
<table>
    <tr class="title">
        <td><input type="checkbox" class="ckbox">全选</td>
        <td>商品信息</td>
        <td>单价</td>
        <td>数量</td>
        <td>金额</td>
        <td>操作</td>
    </tr>
    <tr>
        <td><input type="checkbox" class="ckbtn"></td>
        <td>
            <img src="img/1.jpg" class="face" align="left">
            <a href="#" class="word">豫竹香辣牛肉方便面60包 袋装速食干吃面干脆面泡面整箱包邮特价</a>
        </td>
        <td><span class="price" data-price="39.00">¥39.00</span></td>
        <td class="btn"><button class="btnleft">-</button><input class="txt" type="text" value="1"><button class="btnright">+</button></td>
        <td><span class="totle" data-totle="39.00">¥39.00</span></td>
        <td>删除</td>
    </tr>
    <tr>
        <td><input type="checkbox" class="ckbtn"></td>
        <td>
            <img src="img/1.jpg" class="face" align="left">
            <a href="#" class="word">豫竹香辣牛肉方便面60包 袋装速食干吃面干脆面泡面整箱包邮特价</a>
        </td>
        <td><span class="price" data-price="39.00">¥39.00</span></td>
        <td class="btn"><button class="btnleft">-</button><input class="txt" type="text" value="1"><button class="btnright">+</button></td>
        <td><span class="totle" data-totle="39.00">¥39.00</span></td>
        <td>删除</td>
    </tr>
    <tr>
        <td><input type="checkbox" class="ckbtn"></td>
        <td>
            <img src="img/1.jpg" class="face" align="left">
            <a href="#" class="word">豫竹香辣牛肉方便面60包 袋装速食干吃面干脆面泡面整箱包邮特价</a>
        </td>
        <td><span class="price" data-price="39.00">¥39.00</span></td>
        <td class="btn"><button class="btnleft">-</button><input class="txt" type="text" value="1"><button class="btnright">+</button></td>
        <td><span class="totle" data-totle="39.00">¥39.00</span></td>
        <td>删除</td>
    </tr>
    <tr>
        <td><input type="checkbox" class="ckbtn"></td>
        <td>
            <img src="img/1.jpg" class="face" align="left">
            <a href="#" class="word">豫竹香辣牛肉方便面60包 袋装速食干吃面干脆面泡面整箱包邮特价</a>
        </td>
        <td><span class="price" data-price="39.00">¥39.00</span></td>
        <td class="btn"><button class="btnleft">-</button><input class="txt" type="text" value="1"><button class="btnright">+</button></td>
        <td><span class="totle" data-totle="39.00">¥39.00</span></td>
        <td>删除</td>
    </tr>
    <tr>
        <td><input type="checkbox" class="ckbtn"></td>
        <td>
            <img src="img/1.jpg" class="face" align="left">
            <a href="#" class="word">豫竹香辣牛肉方便面60包 袋装速食干吃面干脆面泡面整箱包邮特价</a>
        </td>
        <td><span class="price" data-price="39.00">¥39.00</span></td>
        <td class="btn"><button class="btnleft">-</button><input class="txt" type="text" value="1"><button class="btnright">+</button></td>
        <td><span class="totle" data-totle="39.00">¥39.00</span></td>
        <td>删除</td>
    </tr>
    <tr>
        <td><input type="checkbox" class="ckbox">全选</td>
        <td colspan="2">已选商品<span class="number">0</span>件</td>
        <td>合计:<span class="totleprice">0</span>元</td>
        <td colspan="2"><button>结算</button></td>
    </tr>
</table>
<script src="js/cart.js"></script>
</body>
</html>

cart.js:

var ckbox = document.getElementsByClassName("ckbox");
var ckbtn = document.getElementsByClassName("ckbtn");
var btnleft = document.getElementsByClassName("btnleft");
var btnright = document.getElementsByClassName("btnright");
var txt = document.getElementsByClassName("txt");
var price=document.getElementsByClassName("price");
var totle=document.getElementsByClassName("totle");
var allprice=document.getElementsByClassName("totleprice")[0];
var number=document.getElementsByClassName("number")[0];
var count=0;
//商品信息前复选框的事件
for(var i=0;i<ckbtn.length;i++){
    ckbtn[i].onclick=function(){
        if(this.checked){
            count++;
        }
        else{
            count--;
        }
        if(count==ckbtn.length){
            ckbox[0].checked=true;
            ckbox[1].checked=true;
        }
        else{
            ckbox[0].checked=false;
            ckbox[1].checked=false;
        }
        ischoose();
    }
}
//全选复选框的事件
for (key in ckbox) {
    ckbox[key].index = key;  //给index属性上绑值,绑个索引
    ckbox[key].onclick = function () {
        ckbox[this.index == 0 ? 1 : 0].checked = !ckbox[this.index == 0 ? 1 : 0].checked;
        if(this.checked){
            for (var i = 0; i < ckbtn.length; i++) {
                ckbtn[i].checked = true;
            }
        }
        else{
            for (var i = 0; i < ckbtn.length; i++) {
                ckbtn[i].checked = false;
            }
        }
        ischoose();
    }
}
//购物车数量的增减事件
for (var i = 0; i < btnleft.length; i++) {
    btnleft[i].index = i;
    btnleft[i].onclick = function () {
        var val = txt[this.index].value;
        val--;
        if (val < 1) {
            val = 1;
        }
        txt[this.index].value = val;
        addprice(this.index,val);
        ischoose();
    }
    btnright[i].index=i;
    btnright[i].onclick = function () {
        var val=txt[this.index].value;
        val++;
        txt[this.index].value=val;
        addprice(this.index,val);
        ischoose();
    }
}
//金额的计算方法
function addprice(index,value){
    totle[index].innerHTML="¥"+(price[index].getAttribute("data-price")*value).toFixed(2);
    totle[index].setAttribute("data-totle",(price[index].getAttribute("data-price")*value).toFixed(2));
}
//判断商品信息前的复选框是否打勾
function ischoose(){
    var totleprice=0;
    var num=0;
    for(var i=0;i<ckbtn.length;i++){
        if(ckbtn[i].checked){
            totleprice+=parseFloat(totle[i].getAttribute("data-totle"));
            num+=parseInt(txt[i].value);
        }
    }
    allprice.innerHTML="¥"+totleprice.toFixed(2);
    number.innerHTML=num;
}

四、遇到的问题及解决方法

  1. 问题:点第一个“全选”按钮时,第二个“全选”按钮自动打钩,反之亦然
    解决思路:存值,即给index属性上绑值,绑个索引
    解决方法:判断当前index属性的索引,找到其相反的索引值(只有两个“全选”按钮,因此若当前索引为0,找到索引为1的那个;反之亦然),使其复选框前打钩
    代码如下
for (key in ckbox) {
        ckbox[key].index = key;  //给index属性上绑值,绑个索引
        ckbox[key].onclick = function () {
            ckbox[this.index == 0 ? 1 : 0].checked = true;
            for (var i = 0; i < ckbtn.length; i++) {
                ckbtn[i].checked = true;
            }
        }
}

知识点ckbox[key].index = key;
Q:事件中,事件里面拿不到外面的索引值,只能拿到最大值,怎样拿到其索引值?
A:法一:做一个闭包处理,有一个自执行函数
法二:在事件外面做一个桥梁,在绑事件的同时,把它所对应的索引绑到当前对象的索引属性上,事件里面直接拿它的索引属性,即当前对象的索引

  1. 问题:单击“全选”前的复选框,进行总金额合计时,默认为NaN
    解决方法:给<td><span class="totle" data-totle="">¥39.00</span></td>中的data-totle属性需设置默认值

  2. 问题:单击“全选”前的复选框,进行总金额合计时,已经选过一次之后,若想修改商品数量,则合计中的金额数没有发生改变
    解决方法:将判断商品信息前的复选框是否打勾的方法(即ischoose())在“-”和“+”的点击事件中调用

  3. 问题:不单击“全选”复选框,进行总金额计算时,若只选了几个,则合计中的金额数没有发生变化
    解决思路:给商品前的复选框添加一个点击事件,事件中调用ischoose()

  4. 问题:将商品信息前的复选框选择之后,又去点“全选”前的复选框,发现变成反选(即商品信息前的复选框中,之前没被选择过的打勾,之前被选择过的勾被取消)
    解决方法:将for循环中的ckbtn[i].checked = !ckbtn[i].checked;改为ckbtn[i].checked=true;

  5. 问题:将商品全选之后,若想取消一个商品,则全选前的复选框依然打勾
    解决思路:点击商品与商品信息前”复选框“的长度相等之后,让”全选“复选框全部选择;只要点击商品的长度比其少,则让其不选择
    用户可能同一件商品连续点击几次,因此需判断当前点的商品是否重复
    解决方法
    (1)定义一个全局变量(即count),若当前商品被选择,则count++;若被选择后又取消,则count- -
    (2)将count与商品信息前”复选框“的长度进行判断:若相等,则两个“全选”复选框被选择,为true;否则,为false
    (3)反选后,count需清零(若不清零,则第一次全选后取消,再进行全选,两个“全选”复选框将不会打勾)

  • 12
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值