一、前言
本文所用的代码是之前看一个大大所写的,忘记大大名字了,侵权立删。实现购物车的方法有很多,我们不应该把重心放在代码上,而是应该放在功能上和逻辑上,这样再复杂的项目,也能从众多功能中一步一步下手。不会代码我们可以去查,直到实现功能为止。
二、功能
1.全选按钮
- 点击后反选按钮的状态改为未选中状态
- 判断点击后是否为选中状态,是则选中所有单选按钮并通过改变classname从而改变背景颜色,否则取消所有单选按钮
//全选
var checkAll = document.getElementsByClassName("checkAll")[0];
var check = document.getElementsByClassName("check");//集合
var bEle = document.getElementsByClassName("b-ele");
var allPrice = document.getElementsByClassName("allPrice")[0];
checkAll.onclick = function () {
for (var i = 0; i < check.length; i++) {
reverseCheck.checked = false
if (checkAll.checked == true) {
check[i].checked = true;
bEle[i].className = "b-ele chooseEle";
} else {//点击全选按钮之后,是未选中状态,则将check状态改为未选中
bEle[i].className = "b-ele";///通过不同的命名改变背景,好方法
check[i].checked = false;
}
}
};
2.反选按钮
- 点击后通过逻辑运算符!改变单选按钮的选中状态
- 判断点击后否为选中状态,是则改背景,否则让全选按钮为非选中状态且改回背景
//反选
var reverseCheck = document.getElementsByClassName("reverseCheck")[0];
reverseCheck.onclick = function () {
//输入数量
for (var i = 0; i < check.length; i++) {
check[i].checked = !check[i].checked;//直接将所有的check状态反选
if (check[i].checked == false) {//点击之后是非选中状态,通过class改背景
bEle[i].className = "b-ele";
checkAll.checked = false;//将全选按钮改为非选中
} else {
bEle[i].className = "b-ele chooseEle";
}
}
};
3.单选按钮
- 点击后是选中状态则改变背景色
- 非选中状态则改回背景色,并取消全选按钮的选中状态
//单选
for (var i = 0; i < bEle.length; i++) {
check[i].checkValue = i;
check[i].onclick = function () {
console.log(this.checked)
if (this.checked == true) {//点击后是选中状态的话
console.log(this.className)
bEle[this.checkValue].className = "b-ele chooseEle";//通过this的i等于bEle的索引值来改变classname
} else {
checkAll.checked = false;//点击后是没选中状态,让背景消失
bEle[this.checkValue].className = "b-ele"
}
}
}
4.数量文本框
- 可以用键盘上的数字和删除按钮backsp进行操作,其它按钮显示NaN(不是数值)
- 当文本框值为0或空值时,让文本框的值改为1
- 文本框中的值为大于1的数字时,计算小计的值,刷新总价格的值
//对文本框的操作
for (var i = 0; i < bEle.length; i++) {
bCountInput[i].countNum = i;
bCountInput[i].onkeydown = function (e) {
if ((e.keyCode >= 48 && e.keyCode <= 57) || e.keyCode == 8||(e.keyCode >= 96 && e.keyCode <= 105)) {//keyCode是键码值,8是backsp,48=0,57=9,是横着的那排数字
} else {
return false//nan
}
};
bCountInput[i].onblur = function () {
if (this.value == "") {
this.value = 1;//空值强改1并刷新小计
bTotal[this.countNum].innerHTML = cacTotal(this.countNum, bPrice, this.value) + "¥";
}
};
bCountInput[i].onkeyup = function () {
if (this.value == "") {//this指向调用它的对象就是文本框拉
bTotal[this.countNum].innerHTML = "0¥";//空白
} else if (this.value == 0) {
this.value = 1;//如果为0,强行改为1,并刷新小计
bTotal[this.countNum].innerHTML = cacTotal(this.countNum, bPrice, this.value) + "¥"
} else {
bTotal[this.countNum].innerHTML = cacTotal(this.countNum, bPrice, this.value) + "¥";//首先文本框只能输入数字和空值,然后检测文本框为0或为空值时改为1且刷新小计
}
allPrice.innerHTML = cacAllPrice(bTotal)+"¥"//刷新总价格
}
}
5.控制数量的加减按钮
- 点击减少按钮,先判断是否为1,为1则提示不能减了1,不为1则做自减计算小计刷新总价
- 点击加按钮,做自加,计算小计刷新总价
//数量进行加减
allPrice.innerHTML = cacAllPrice(bTotal)+"¥";//先把所有小计的函数给写出来
for (var i = 0; i < bEle.length; i++) {
buttonSub[i].countNum = i;
buttonSub[i].onclick = function () {
if (bCountInput[this.countNum].value == 1) {//数量为1时提示
alert("该宝贝不能减少了噢!")
} else {
var value = --bCountInput[this.countNum].value;//数量减一
bTotal[this.countNum].innerHTML = cacTotal(this.countNum, bPrice, value) + "¥";//括号里的是形参,计算小计
allPrice.innerHTML = cacAllPrice(bTotal)+"¥"//重新刷新总价
}
};
buttonAdd[i].countNum = i;
buttonAdd[i].onclick = function () {
var value = ++bCountInput[this.countNum].value;//数量加一
bTotal[this.countNum].innerHTML = cacTotal(this.countNum, bPrice, value) + "¥";//计算小计
allPrice.innerHTML = cacAllPrice(bTotal)+"¥"
}
}
6.删除按钮
- 使对应的商品从列表中删除
- 重新给所有对象加索引值
- 刷新总价
//删除元素
console.log(bEle.length);
for (var i = 0; i < bEle.length; i++) {
eleDelete[i].value = i;
eleDelete[i].onclick = function () {
bList.removeChild(bEle[this.value]);//删除节点
for(var k = 0;k<bEle.length;k++){
//重新给所有对象的value/countNum索引值
eleDelete[k].value = k;//对删除按钮重新上值
buttonSub[k].countNum=k;//对数量加重新上编号(索引)
bCountInput[k].countNum=k;//文本框
buttonAdd[k].countNum=k;
}
allPrice.innerHTML = cacAllPrice(bTotal)+"¥"//刷新总价
}
}
}
7.小计
- 设置形参,通过价格=单价*数量得到小计
//计算小计
function cacTotal(index, priceObj, value) {//形参
return parseFloat(priceObj[index].innerHTML) * parseInt(value);//括号里是单价*数量,parseFloat()返回从位置0开始查看每一个字符,直到找到第一个非有效字符,然后把之前的字符串转换为数字
}
8.总价
- .遍历所有的小计,挨个相加得到总价
//计算总价
function cacAllPrice(bTotal) {
var totalPrice=0;//随便定义一个变量为0
for(var i=0;i<bTotal.length;i++){//遍历所有的小计
totalPrice += parseFloat(bTotal[i].innerHTML)//加
}
return totalPrice;//返回总价格
}
三、代码部分
.
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
* {
margin: 0;
padding: 0;
font-size: 14px;
}
.all {
width: 1000px;
margin: auto;
}
.b-top {
display: flex;
flex-direction: row;
background: #ffe0cb;
height: 30px;
line-height: 30px;
}
.b-info {
flex: 1;
text-align: center;
}
.b-length {
flex: 2;
}
.b-ele {
display: flex;
flex-direction: row;
height: 70px;
line-height: 70px;
padding: 10px 0;
border-bottom: 1px dashed silver;
}
.b-ele div {
text-align: center;
}
.chooseEle {
background: pink;
}
.b-button {
color: blue;
width: 60px;
height: 25px;
text-align: center;
line-height: 25px;
background: silver;
border: none;
}
.b-count-button {
width: 25px;
height: 25px;
border: none;
color: blue;
background: orange;
}
.b-count-input {
border: none;
height: 20px;
width: 25px;
outline: none;
text-align: center;
}
img {
width: 25px;
height: 25px;
}
.b-display {
display: flex;
justify-content: space-between;
}
.b-display div {
width: 120px;
height: 40px;
line-height: 40px;
}
.left {
text-align: center;
}
.right button {
width: 100%;
height: 100%;
background: red;
color: white;
text-align: center;
border: none;
}
</style>
</head>
<body>
<div class="all">
<div class="b-top">
<div class="b-info">
<input type="checkbox" class="checkAll"/>全选
</div>
<div class="b-info b-length">商品名称</div>
<div class="b-info">图片</div>
<div class="b-info">单价</div>
<div class="b-info b-length">数量</div>
<div class="b-info">小计</div>
<div class="b-info">操作</div>
</div>
<div class="b-list"></div>
<div class="b-display">
<div class="left">
<input type="checkbox" class="reverseCheck"/>反选
</div>
<div class="center">
总价:<span class="allPrice">0¥</span>
</div>
<div class="right">
<button>去结算></button>
</div>
</div>
</div>
</body>
<script>
var cart = [
{
"id": "101321XNMNSDJYE6871DAS21",
"name": "华为nova5 pro",
"src": "./cartimage/415d8ef0da06eb00.png",
"price": "1499",
"totle": "1499",
"num": 1
},//数组字面量里面写入四个对象
{
"id": "101321XNMNSDJYE6871DAS21",
"name": "华为nova5 pro",
"src": "./cartimage/415d8ef0da06eb00.png",
"price": "1599",
"totle": "1599",
"num": 1
},
{
"id": "101321XNMNSDJYE6871DAS21",
"name": "华为nova5 pro",
"src": "./cartimage/415d8ef0da06eb00.png",
"price": "1699",
"totle": "1699",
"num": 1
},
{
"id": "101321XNMNSDJYE6871DAS21",
"name": "华为nova5 pro",
"src": "./cartimage/415d8ef0da06eb00.png",
"price": "1799",
"totle": "1799",
"num": 1
}
];//为购物车建立数组对象
var bTop = document.getElementsByClassName("b-top")[0];//获取info信息栏
var bList = document.getElementsByClassName("b-list")[0];//获取表单盒子
//动态创建页面-创四个商品盒
for (var i = 0; i < cart.length; i++) {//for循环 !!!!别用let声明,var可以重复声明,let不行
var bEle = document.createElement("div");//创建一个div
bEle.className = "b-ele";//div的classname
bList.appendChild(bEle);//将新建的div放到list里面
var bNode = document.createElement("div");//创
bNode.className = "b-info";
var bInput = document.createElement("input");//创建一个表单
bInput.type = "checkbox";//类型为复选框
bInput.className = "check";//classname
bNode.appendChild(bInput);//将表单放在创建的div中
bEle.appendChild(bNode);//将上面的div放到上上面的div中
var bNode = document.createElement("div");
bNode.className = "b-info b-length";
bNode.innerHTML = cart[i].name;//将name写进去
bEle.appendChild(bNode);//继续放到bEle里面
var bNode = document.createElement("div");
bNode.className = "b-info";
bNode.style.lineHeight = "80px"
var bImg = document.createElement("img");//放照片
bImg.src = cart[i].src;
bNode.appendChild(bImg);
bEle.appendChild(bNode);
var bNode = document.createElement("div");
bNode.className = "b-info b-price";
bNode.innerHTML = cart[i]["price"] + "¥";//单价
bEle.appendChild(bNode);
var bNode = document.createElement("div");
bNode.className = "b-info b-length";
var bCountButtonSub = document.createElement("button");
bCountButtonSub.className = "b-count-button buttonSub";
bCountButtonSub.innerHTML = "-";
var bCountInput = document.createElement("input");
bCountInput.type = "text";
bCountInput.className = "b-count-input";//数量文本框
bCountInput.value = cart[i].num;
var bCountButtonAdd = document.createElement("button");
bCountButtonAdd.className = "b-count-button buttonAdd";//加减按钮
bCountButtonAdd.innerHTML = "+";
bNode.appendChild(bCountButtonSub);
bNode.appendChild(bCountInput);
bNode.appendChild(bCountButtonAdd);
bEle.appendChild(bNode)
var bNode = document.createElement("div");
bNode.className = "b-info b-total";
bNode.innerHTML = cart[i].totle + "¥";//小记
bEle.appendChild(bNode);
var bNode = document.createElement("div");
bNode.className = "b-info";
var bCountButton = document.createElement("button");//删除按钮
bCountButton.className = "b-button eleDelete";
bCountButton.innerHTML = "删除";
bNode.appendChild(bCountButton)
bEle.appendChild(bNode)
}
;
//全选
var checkAll = document.getElementsByClassName("checkAll")[0];
var check = document.getElementsByClassName("check");//集合
var bEle = document.getElementsByClassName("b-ele");
var allPrice = document.getElementsByClassName("allPrice")[0];
checkAll.onclick = function () {
for (var i = 0; i < check.length; i++) {
reverseCheck.checked = false
if (checkAll.checked == true) {
check[i].checked = true;
bEle[i].className = "b-ele chooseEle";
} else {//点击全选按钮之后,是未选中状态,则将check状态改为未选中
bEle[i].className = "b-ele";///通过不同的命名改变背景,好方法
check[i].checked = false;
}
}
};
//反选
var reverseCheck = document.getElementsByClassName("reverseCheck")[0];
reverseCheck.onclick = function () {
//输入数量
for (var i = 0; i < check.length; i++) {
check[i].checked = !check[i].checked;//直接将所有的check状态反选
if (check[i].checked == false) {//点击之后是非选中状态,通过class改背景
bEle[i].className = "b-ele";
checkAll.checked = false;//将全选按钮改为非选中
} else {
bEle[i].className = "b-ele chooseEle";
}
}
};
//单选
for (var i = 0; i < bEle.length; i++) {
check[i].checkValue = i;
check[i].onclick = function () {
console.log(this.checked)
if (this.checked == true) {//点击后是选中状态的话
console.log(this.className)
bEle[this.checkValue].className = "b-ele chooseEle";//通过this的i等于bEle的索引值来改变classname
} else {
checkAll.checked = false;//点击后是没选中状态,让背景消失
bEle[this.checkValue].className = "b-ele"
}
}
}
window.onload = function (ev) {
//
var buttonSub = document.getElementsByClassName("buttonSub");//上面创建的数量减小按钮的合集哦
var buttonAdd = document.getElementsByClassName("buttonAdd");//数量增加按钮
var bCountInput = document.getElementsByClassName("b-count-input");//数量文本框
var bEle = document.getElementsByClassName("b-ele");//信息盒的集合
var bTotal = document.getElementsByClassName("b-total");//小计
var bPrice = document.getElementsByClassName("b-price");//单价
var eleDelete = document.getElementsByClassName("eleDelete");//删除
var allPrice = document.getElementsByClassName("allPrice")[0];//总价格
//数量进行加减
allPrice.innerHTML = cacAllPrice(bTotal)+"¥";//先把所有小计的函数给写出来
for (var i = 0; i < bEle.length; i++) {
buttonSub[i].countNum = i;
buttonSub[i].onclick = function () {
if (bCountInput[this.countNum].value == 1) {//数量为1时提示
alert("该宝贝不能减少了噢!")
} else {
var value = --bCountInput[this.countNum].value;//数量减一
bTotal[this.countNum].innerHTML = cacTotal(this.countNum, bPrice, value) + "¥";//括号里的是形参,计算小计
allPrice.innerHTML = cacAllPrice(bTotal)+"¥"//重新刷新总价
}
};
buttonAdd[i].countNum = i;
buttonAdd[i].onclick = function () {
var value = ++bCountInput[this.countNum].value;//数量加一
bTotal[this.countNum].innerHTML = cacTotal(this.countNum, bPrice, value) + "¥";//计算小计
allPrice.innerHTML = cacAllPrice(bTotal)+"¥"
}
}
//对文本框的操作
for (var i = 0; i < bEle.length; i++) {
bCountInput[i].countNum = i;
bCountInput[i].onkeydown = function (e) {
if ((e.keyCode >= 48 && e.keyCode <= 57) || e.keyCode == 8||(e.keyCode >= 96 && e.keyCode <= 105)) {//keyCode是键码值,8是backsp,48=0,57=9,是横着的那排数字
} else {
return false//nan
}
};
bCountInput[i].onblur = function () {
if (this.value == "") {
this.value = 1;//空值强改1并刷新小计
bTotal[this.countNum].innerHTML = cacTotal(this.countNum, bPrice, this.value) + "¥";
}
};
bCountInput[i].onkeyup = function () {
if (this.value == "") {//this指向调用它的对象就是文本框拉
bTotal[this.countNum].innerHTML = "0¥";//空白
} else if (this.value == 0) {
this.value = 1;//如果为0,强行改为1,并刷新小计
bTotal[this.countNum].innerHTML = cacTotal(this.countNum, bPrice, this.value) + "¥"
} else {
bTotal[this.countNum].innerHTML = cacTotal(this.countNum, bPrice, this.value) + "¥";//首先文本框只能输入数字和空值,然后检测文本框为0或为空值时改为1且刷新小计
}
allPrice.innerHTML = cacAllPrice(bTotal)+"¥"//刷新总价格
}
}
//删除元素
console.log(bEle.length);
for (var i = 0; i < bEle.length; i++) {
eleDelete[i].value = i;
eleDelete[i].onclick = function () {
bList.removeChild(bEle[this.value]);//删除节点
for(var k = 0;k<bEle.length;k++){
//重新给所有对象的value/countNum索引值
eleDelete[k].value = k;//对删除按钮重新上值
buttonSub[k].countNum=k;//对数量加重新上编号(索引)
bCountInput[k].countNum=k;//文本框
buttonAdd[k].countNum=k;
}
allPrice.innerHTML = cacAllPrice(bTotal)+"¥"//刷新总价
}
}
}
//计算小计
function cacTotal(index, priceObj, value) {//形参
return parseFloat(priceObj[index].innerHTML) * parseInt(value);//括号里是单价*数量,parseFloat()返回从位置0开始查看每一个字符,直到找到第一个非有效字符,然后把之前的字符串转换为数字
}
//计算总价
function cacAllPrice(bTotal) {
var totalPrice=0;//随便定义一个变量为0
for(var i=0;i<bTotal.length;i++){//遍历所有的小计
totalPrice += parseFloat(bTotal[i].innerHTML)//加
}
return totalPrice;//返回总价格
}
</script>
</html>