tml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<script src="js/jquery-3.4.1.min.js"></script>
<link rel="stylesheet" href="bootstrap-3.4.1/css/bootstrap.min.css">
<script src="js/jquery_shopping.js"></script>
</head>
<body>
<div class="panel-group">
<div class="panel panel-primary">
<table class="table table-bordered table-striped table-hover table-condensed" id="tab_s">
<thead>
<tr class="info">
<th>商品名称</th>
<th>单价</th>
<th>数量</th>
<th>小计</th>
<th>操作</th>
</tr>
</thead>
<tbody id="tby">
<tr>
<td>电脑</td>
<td class="price">¥3999.00</td>
<td>
<div class="row">
<div class="col-md-1">
<button type="button" class="btn btn-default btn-sm" name="sub">
<span class="glyphicon glyphicon-minus" aria-hidden="true"></span>
</button>
</div>
<div class="col-md-1">
<input class="form-control input-sm" type="text" name="num" value="1" placeholder="请输入数量">
</div>
<div class="col-md-1">
<button type="button" class="btn btn-default btn-sm" name="add">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
</button>
</div>
</div>
</td>
<td class="small_total">¥3999.00</td>
<td>
<button type="button" class="btn btn-default btn-sm" name="delete">
<span class="glyphicon glyphicon-remove"> 删除</span>
</button>
</td>
</tr>
<tr>
<td>手机</td>
<td class="price">¥1998.00</td>
<td>
<div class="row">
<div class="col-md-1">
<button type="button" class="btn btn-default btn-sm" name="sub">
<span class="glyphicon glyphicon-minus" aria-hidden="true"></span>
</button>
</div>
<div class="col-md-1">
<input class="form-control input-sm" type="text" name="num" value="1" placeholder="请输入数量">
</div>
<div class="col-md-1">
<button type="button" class="btn btn-default btn-sm" name="add">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
</button>
</div>
</div>
</td>
<td class="small_total">¥1998.00</td>
<td>
<button type="button" class="btn btn-default btn-sm" name="delete">
<span class="glyphicon glyphicon-remove"> 删除</span>
</button>
</td>
</tr>
<tr>
<td>空调</td>
<td class="price">¥2099.00</td>
<td>
<div class="row">
<div class="col-md-1">
<button type="button" class="btn btn-default btn-sm" name="sub">
<span class="glyphicon glyphicon-minus" aria-hidden="true"></span>
</button>
</div>
<div class="col-md-1">
<input class="form-control input-sm" type="text" name="num" value="1" placeholder="请输入数量">
</div>
<div class="col-md-1">
<button type="button" class="btn btn-default btn-sm" name="add">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
</button>
</div>
</div>
</td>
<td class="small_total">¥2099.00</td>
<td>
<button type="button" class="btn btn-default btn-sm" name="delete">
<span class="glyphicon glyphicon-remove"> 删除</span>
</button>
</td>
</tr>
</tbody>
</table>
<div class="panel-footer">
<span>已选<span style="color: red;" class="num_sum">1</span>件商品</span>
<span>总计:</span>
<span class="sum" style="color: red;">0</span>
<div>
<button type="button" class="btn btn-default btn-sm" name="delSome">
删除选中商品
</button>
<button type="button" class="btn btn-default btn-sm" name="delAll">
清空购物车
</button>
</div>
</div>
</div>
</div>
</body>
</html>
Js代码:
$(function(){
function initTableCheckbox() {
var $thr = $('table thead tr');
var $checkAllTh = $('<th><input type="checkbox" id="checkAll" name="checkAll" /></th>');
/*将全选/反选复选框添加到表头最前,即增加一列*/
$thr.prepend($checkAllTh);
var $checkAll = $thr.find('input');
$checkAll.click(function(event){
/*将所有行的选中状态设成全选框的选中状态*/
$tbr.find('input').prop('checked',$(this).prop('checked'));
/*并调整所有选中行的CSS样式*/
if ($(this).prop('checked')) {
$tbr.find('input').parent().parent().addClass('warning');
}
else{
$tbr.find('input').parent().parent().removeClass('warning');
}
getSum();
/*阻止向上冒泡,以防再次触发点击操作*/
event.stopPropagation();
});
/*点击全选框所在单元格时也触发全选框的点击操作*/
$checkAllTh.click(function(){
$(this).find('input:[type="checkbox"]').click();
});
var $tbr = $('table tbody tr');
var $checkItemTd = $('<td><input type="checkbox" name="checkItem" class="chk_itm"/></td>');
/*每一行都在最前面插入一个选中复选框的单元格*/
$tbr.prepend($checkItemTd);
/*点击每一行的选中复选框时*/
/*
$tbr.find('input').click(function(event){
//调整选中行的CSS样式
$(this).parent().parent().toggleClass('warning');
//如果已经被选中行的行数等于表格的数据行数,将全选框设为选中状态,否则设为未选中状态
$checkAll.prop('checked',$tbr.find('input:checked').length == $tbr.length ? true : false);
//阻止向上冒泡,以防再次触发点击操作
event.stopPropagation();
});
//点击每一行时也触发该行的选中操作
$tbr.click(function(){
$(this).find('input').click();
});
*/
}
initTableCheckbox();
getSum();
$(".chk_itm").change(function() {
getSum();
});
//添加商品
$("button[name='add']").click(function() {
let n = parseInt($(this).parent().siblings().find("input[name='num']").val());
console.log("添加商品的num:"+n);
n++;
$(this).parent().siblings().find("input[name='num']").val(n);
let price = $(this).parent().parent().parent().siblings(".price").html();
price = price.substr(1);
console.log("添加商品的price:"+price);
$(this).parent().parent().parent().siblings(".small_total").text("¥" + (n * price).toFixed(2));
getSum();
});
//减少商品
$("button[name='sub']").click(function() {
let n = parseInt($(this).parent().siblings().find("input[name='num']").val());
console.log("减少商品的num:"+n);
if (n === 1) {
return false;
}
n--;
$(this).parent().siblings().find("input[name='num']").val(n);
let price = $(this).parent().parent().parent().siblings(".price").html();
price = price.substr(1);
console.log("减少商品的price:"+price);
$(this).parent().parent().parent().siblings(".small_total").text("¥" + (n * price).toFixed(2));
getSum();
});
$("input[name='num']").change(function() {
let n = $(this).val();
console.log("数量num:"+n);
let price = $(this).parent().parent().parent().siblings(".price").html();
price = price.substr(1);
console.log("价格price:"+price);
$(this).parent().parent().parent().siblings(".small_total").text("¥" + (n * price).toFixed(2));
getSum();
});
function getSum() {
let count = 0; //计算总件数
let money = 0; //计算总价钱
$("input[name='num']").each(function(index) {
if ($(".chk_itm").eq(index).prop("checked") == true) {
count += parseInt($("input[name='num']").eq(index).val());
money += parseFloat($(".small_total").eq(index).text().substr(1));
}
});
$(".num_sum").html(count);
$(".sum").html(money.toFixed(2));
}
//点击删除之后一定是删除当前的商品,获取this
$("button[name='delete']").click(function() {
//删除的是当前的商品
$(this).parent().parent().remove();
$(".chk_itm").change();
getSum();
clearCheckAll();
});
//删除选定的商品:小的复选框如果选中就删除对应的商品
//删除的是选中的商品
$("button[name='delSome']").click(function() {
//删除的是选中的商品
$(".chk_itm:checked").parent().parent().remove();
getSum();
clearCheckAll();
});
//清空购物车
$("button[name='delAll']").click(function() {
$("#tby").empty();
getSum();
clearCheckAll();
});
function clearCheckAll() {
if ($("#tby").innerText == '') {
$(".checkAll").prop("checked", false);
}
}
});
效果
案例和由此案例重点讲解的知识点介绍
案例代码实现
数据类型知识点详解
案例相关效果图
该案例涉及到的知识点
js变量
js数据类型
js运算符
第一步:编写表单的html
依次拷贝出两个tr,让我们购物车多几件商品,只需要拷贝上一行代码,然后修改一下标题。价格即可
第二步:编写该表单的样式css
第三步:引入方便的jquery库,方便我们使用
第四步:绑定减少数量的按键,并获取上一元素的单价,将字符串转换成数字,同时获取当前input的数量,并进行数据计算
第五步:依照减少商品数量的方法,仿写增加商品数量
1. JavaScript变量
变量的语法:
变量定义: var 自定义名称;
<script>
var name=“张三”; //张三为变量 name是变量名 var 关键字定义变量
</script>
注意: = 为赋值符号,不是我们理解的等号
变量命名的规范:
变量名必须以字符或下划线“_”开头
变量可以包含数字、从A至Z的大小字母
JavaScript严格区分大小写,computer和Computer是两个完全不同的变量
禁止使用javascript的保留关键字作为变量名
2. JavaScript数据类型
数字类型(Number)
1: 最基本的数据类型
2: 不区分整型数值和浮点型数值
3: 能表示的最大值是±1.7976931348623157乘以10的308次方
能表示的最小值是±5 乘以10的-324次方
4:包含十六进制数据,以 0x开头 0到9之间的数字,a(A)-f(F)之间字母构成。 a-f对应的数字是10-15
5: 八进制直接以数字0开始,有0-7之间的数字组成。
字符串类型(String)
字符串由单引号或双引号括起
例如单独一个字母也被称为字符串(例如:‘a’)
转义字符 \" \'
比较运算符:> ,<, ==, !=
var a=1; var b=2; alert(a>b);
布尔类型:Boolean
Boolean类型仅有两个值:true和false,也代表1和0,实际运算中true=1,false=0
JavaScript 特殊类型
取值null 含义:值为空(主动)
取值undefined 含义:变量未初始化
先让我们看一下静态页面的效果图:
简单说一下这个功能模块的需求:
现在让我们开始吧
一 ,创建一个Vue对象,设置好数据。
var cart; //全局Vue对象 //通过封装一个方法来创建Vue对象 function createVue(list) { //传入通过后台获取的list cart = new Vue({ el:'#cart', data(){ return { list:list //商品列表 } } }); }
二 ,假设从后台请求到数据,然后赋值到Vue对象中
window.onload = function () { //请求后台代码 。。。。 //请求成功后将获得的list赋值给cart的list let list = [ { goodsTitle: "卫龙辣条", //商品名 specifications: "大包", //商品规格 unitPrice: "5", //商品单价 subimage1Filename :"20180317eeftyd.jpg", //商品图片名 purchaseQuantity: 6 //商品数量 }, { goodsTitle: "雕牌洗衣粉", specifications: "大包", unitPrice: "13", subimage1Filename: "20180317ggptfg.jpg", purchaseQuantity: 1 }, { goodsTitle: "旺仔牛奶", specifications: "20盒装", unitPrice: "45", subimage1Filename: "20180317feftyp.jpg", purchaseQuantity: 1 }]; createVue(list); //执行创建Vue对象方法 } );
三 ,修改html部分代码,将数据展示出来
<tr v-for="(item,index) in list"> <td> <input type="checkbox" :id="'check'+index" name="checkboxs" /> <label :for="'check'+index"></label> </td> <td> <img :src="'路径前缀/'+item.subimage1Filename" /> </td> <td style="text-align:left;"> <p>{{item.goodsTitle}}</p> <p>规格:{{item.specifications}}</p> </td> <td>¥{{item.unitPrice}}</td> <td class="adddel"> <em v-on:click="minius(index)">-</em> <input type="number" v-model.number="item.purchaseQuantity" /> <em v-on:click="add(index)">+</em> </td> <td>¥{{item.unitPrice * item.purchaseQuantity}}</td> <td><button v-on:click="checkDel(index)">删除</button></td> </tr>
这样就能将单个商品部分全部循环打印出来,并且将对应的信息打印在对应位置。效果图如下:
四,实现全选和勾选时候总价的计算,这部分算是有点挑战了。我的思路是在Vue对象中新增加一个数据用来标识商品的选中状态,所以创建Vue方法中的代码改成如下所示:
cart = new Vue({ el: '#cart', data() { return { list: list, checkeds: new Array(list.length) //初始化成list的长度 } });
然后在html中将商品对应的checkbox与checkeds绑定起来,修改后的代码如下:
<input type="checkbox" :id="'check'+index" name="checkboxs" v-model="checkeds[index]" />
利用computed属性计算价格总和:
sum () { let sum = 0; for (let i in this.list) { if (this.checkeds[i]) //如果checkeds[i]的结果为truth,则进行累加 sum += this.list[i].unitPrice * this.list[i].purchaseQuantity; } return sum; }
HTML部分,我们在对应位置用{{sum}}带入就能进行显示了。这样就能实现计算勾选过的商品小计之和了。接下来实现全选功能,在methods属性中添加一个方法checkAll,具体代码如下:
checkAll (event) { //这里的event就是全选checkbox对象 if (event.checked) { //如果全选的checkbox选中,将checkeds所有的值设置为true,对应商品checkbox的选中状态自动更新 for (let i = 0; i < this.checkeds.length; i++) { Vue.set(this.checkeds, i, true); } else { //否则就进行与上面相反的操作 for (let i = 0; i < this.checkeds.length; i++) { Vue.set(this.checkeds, i, false); } } }
经过上面的一波操作,已经可以实现全选和点选时候的价格之和计算。我们还要统计商品选中的数量,这个很简单,同样使用computed属性,对checkeds中结果为truth的进行统计就好了,代码如下:
checkNum: function () { let num = 0; for (let i in this.checkeds) { if (this.checkeds[i]) { num++; } } return num; }
然后在html中的对应位置用{{checkNum}}代入即可。现在我们已经实现了近一半需求,让我们继续完成他们吧! 五 ,实现购物车物品单个删除功能,这个就很简单啦,我们在methods中增加一个del方法,使用js数组的splice方法就可以实现。
del (index) { this.list.splice(index, 1); //只需要从数组中移除对应项,视图会自动更新,不得不说,Vue太棒啦! this.checkeds.splice(index,1); //同时删除对应的选中状态标识 }
然后就是给删除按钮绑定点击事件(index是循环列表时候的下标):
<button v-on:click="del(index)">删除</button>
这样我们就轻松实现了删除单个商品的需求,当然防止用户误删,在用户点击删除按钮时我们可以弹出一个确认框提示用户,这里我们就不去实现了。 六 ,实现购物车单个商品的数量增加,减少,并实时更新商品的小计。首先在methods中添加增加方法add和减少方法minius:
add (index) { this.list[index].purchaseQuantity++; //这里按理来说应该查询后台对应商品库存量来进行限制的,这里不涉及到后台所以没加 }, minius (index) { if (this.list[index].purchaseQuantity > 1) { //这里添加一个限制,最少要有一个商品 this.list[index].purchaseQuantity--; } }
然后我们在对应的加和减的按钮上绑定事件来触发这两个方法(index为列表循环时候的下标):
<td class="adddel"> <em v-on:click="minius(index)">-</em> <input type="number" v-model.number="item.purchaseQuantity" /> <em v-on:click="add(index)">+</em> </td> <td>¥{{item.unitPrice * item.purchaseQuantity}}</td>
从上面的代码可以看到我们在小计一栏直接进行商品单价和数量相乘,这样就可以实现实时更新了。
至此,我们的需求就算是完成了,最后给大家留两个小问题思考一下
一 ,如何实现批量删除? 二 ,在全选之后,我们取消了一个商品的状态,全选框的选中状态仍然是选中的,此时应该是不选中的,或者当我们一个一个把商品的选中状态全部勾选,全选框的状态仍然是补选中的,此时应该是选中状态(如下两图所示),这个现象如何解决?
*请认真填写需求信息,我们会在24小时内与您取得联系。