原生js编写小米购物车案例
思路
一、将数据渲染到下方ul中
1.遍历数据添加到li标签内
二、渲染购物车内容,将ul中li添加到购物车。添加点击事件
1.加入购物车内容
1.判断购物车内需不需要添加此类商品,
(1)如果不需要,value值加一 调用函数计算(小计、总价、件数)
(2)如果需要,渲染购物车内容 调用函数 计算 (小计、总价、件数)
判断复选全选状态
2.购物车内容
1.全选复选框
(1)全选注册事件:复选框状态同步全选框
(2)封装(复选框状态判断全选框状态)
(3)复选框注册事件:1.复选框都选中,全选框选中
2.复选框一个不选中,全选框不选中
3.调用函数 判断复选全选状态
计算 (小计、总价、件数)
2.加号减号改变value值
1.加号 (1)注册事件 兄弟元素value++
(2)调用函数 计算 (小计、总价、件数)
2.减号 (1)注册事件 判断value是否为‘1’1>alert不能少于一
!1>兄弟元素value--
(2)调用函数 计算 (小计、总价、件数)
3.删除按钮添加事件
1.confirm(确认)tr删除
2.else(无按钮时)全选状态false
3.调用函数 判断复选全选状态
计算(小计、总价、件数)
3.封装函数(小计、总价、件数)
三、代码(无图)(部分样式未修改)
1.html部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>购物车</title>
<style>
* {
margin: 0px;
padding: 0px;
}
.top {
width: 1200px;
margin: 50px auto;
}
ul li {
list-style: none;
}
.main {
width: 1200px;
height: 600px;
margin: 50px auto;
}
.main ul li {
width: 200px;
height: 280px;
background-color: #ccc;
float: left;
/*display: flex;*/
margin: 0 20px 20px 0;
border: 1px solid #000;
text-align: center;
}
.top {
width: 1200px;
margin: 50px;
margin: 0px auto;
}
.add {
width: 80px;
height: 30px;
border: 1px solid #000;
margin: 20px auto;
text-align: center;
line-height: 30px;
}
.add:hover {
cursor: pointer;
background-color: pink;
}
.da {
/*display: block;*/
width: 30px;
height: 30px;
border-style: none;
text-align: center;
background-color: #fff;
}
td {
text-align: center;
}
.dis {
border: 1px solid #000;
width: 100px;
height: 31px;
margin: 50px auto;
}
table {
width: 1090px;
}
tbody tr {
height: 50px;
}
.foot {
float: left;;
height: 50px;
width: 1090px;
/*background-color: red;*/
line-height: 50px;
margin: 20px auto;
}
.foot div {
float: left;
font-size: 20px;
}
.foot div:nth-child(1){
margin-left: 30px;
}
.foot div:nth-child(2){
margin-left: 550px;
}
.foot div:nth-child(3) input {
display: block;
width: 150px;
height: 50px;
border-style: none;
background-color: orange;
font-size: 20px;
color: #fff;
}
.foot div:nth-child(3) {
float: right;
}
</style>
</head>
<body>
<div class="top">
<table border="1" width="1200" cellpadding="20" cellspacing="0">
<thead>
<tr>
<th><input type="checkbox" class="quan"></th>
<th>全选</th>
<th>商品名称</th>
<th>单价</th>
<th>数量</th>
<th>小计</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
<!-- <tfoot class="foot">
<tr>
td
</tr>
<div>已选择<span>0</span>件</div>
<div>合计:<span>0</span>元</div>
<div><input type="button" value="去结算"></div>
</tfoot> -->
</table>
<div class="foot">
<div>已选择<span class="piece">0</span>件</div>
<div>合计:<span class="heji">0</span>元</div>
<div><input type="button" value="去结算"></div>
</div>
<div class="main">
<ul class="box">
<!-- <li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li> -->
</ul>
</div>
</div>
</body>
<script src="./js/1.js"></script>
</html>
2.js部分
var goods = [{
goodsName: 'Redmi手表2',
price: 379,
count: 12.1,
goodsSrc: './images/pic_1.png'
}, {
goodsName: 'Redmi 9A',
price: 599,
count: 113.4,
goodsSrc: './images/pic_2.png'
}, {
goodsName: 'Aqara智能门锁 NFC卡',
price: 49,
count: 3.5,
goodsSrc: './images/pic_3.png'
}, {
goodsName: '小米USB-C数据线 100cm',
price: 9.9,
count: 92.3,
goodsSrc: './images/pic_4.png'
}, {
goodsName: '小米无线鼠标 Lite',
price: 39,
count: 25.1,
goodsSrc: './images/pic_5.png'
}, {
goodsName: '知吾煮不粘炒锅 米家定制',
price: 199,
count: 1.7,
goodsSrc: './images/pic_6.png'
}, {
goodsName: 'Xiaomi11 青春版',
price: 1999,
count: 109.3,
goodsSrc: './images/pic_7.png'
}, {
goodsName: 'Redmi K40',
price: 1999,
count: 106.5,
goodsSrc: './images/pic_8.png'
}, {
goodsName: '小米平板5',
price: 1999,
count: 51.4,
goodsSrc: './images/pic_9.png'
}, {
goodsName: '小米智能摄像机2 云台版',
price: 249,
count: 8,
goodsSrc: './images/pic_10.png'
}, ]
// 获取全选按钮的节点
var quan=document.getElementsByClassName('quan')[0];
// 获取每个复选框的节点
var son=document.getElementsByClassName('son');
// 数据渲染
// 讲数据渲染到ul li中
var ul=document.querySelector('.box');
var tbody=document.querySelector('tbody');
// 遍历数据
for(var i=0;i<goods.length;i++){
var li=document.createElement('li');
// 将数据添加进的li里面
li.innerHTML='<img src="'+goods[i].goodsSrc+'">'+
'<p>'+goods[i].goodsName+'</p>'+
'<span>'+goods[i].price+'元</span>'+
'<p>'+goods[i].count+'万人好评</span>'+
'<div class="add">添加</div>';
ul.appendChild(li);
}
// 获取加入购物车的按钮
var adds=document.getElementsByClassName('add');
// 给添加购物车按钮添加点击事件
for(var i=0;i<adds.length;i++){
adds[i].onclick=function(){
//判断购物车有没有要添加的这商品
//获取到每一行
var trs=document.querySelectorAll('tbody tr');
// 获取到我点击的每一行的商品名称
var trs_name=this.parentNode.children[1].innerHTML;
var zhis=document.getElementsByClassName('zhi');
//循环每一个行,就是每一行里面的商品名称
for(var z=0;z<trs.length;z++){
if(trs[z].children[2].innerHTML==trs_name){
zhis[z].value = parseInt(zhis[z].value) + 1
compute()
return
}
}
// // 获取全选按钮的节点
// var quan=document.getElementsByClassName('quan')[0];
// // 获取每个复选框的节点
// var son=document.getElementsByClassName('son');
var spimg = this.parentNode.children[0].src;
var spname = this.parentNode.children[1].innerText;
var spp = this.parentNode.children[2].innerText;
var tr = document.createElement('tr');
tr.innerHTML='<td><input type="checkbox" class="son" checked></td>'+
'<td><img src="'+spimg+'"></td>'+
'<td class="spname">'+spname+'</td>'+
'<td class="danjia">'+spp+'</td>'+
'<td><div class="dis"><input type="button" value="-" class="da jian"/><input type="text" value="1" class="da zhi"/><input type="button" value="+" class="da jia"/></div></td>'+
'<td class="sub">'+spp+'</td>'+
'<td><a href="#" class="del">删除</a></td>';
tbody.appendChild(tr);
// 函数调用
compute();
fn();
// 全选反选
quan.onclick=function(){
for(var i=0;i<son.length;i++){
son[i].checked=quan.checked;
}
}
// 封装一个标记变量,记录复选框的状态,来判断全选框的状态
function fn (){
var flag = true;
for(var i=0;i<son.length;i++){
if(!son[i].checked){
flag=false;
}
}
quan.checked=flag;
}
// 复选框都选中,全选框选中,复选框一个不选中,全选框不选中
for(var j=0;j<son.length;j++){
son[j].onclick=function(){
fn();
compute();
}
}
// 给加添号加点击事件
var jia = document.getElementsByClassName('jia');
for(var k=0;k<jia.length;k++){
jia[k].onclick=function(){
this.previousElementSibling.value++;
compute();
}
}
//给减号添加点击事件
var jian=document.getElementsByClassName('jian');
for(var l=0;l<jian.length;l++){
jian[l].onclick=function(){
if(this.nextElementSibling.value<=1){
alert('该商品不能小于1了');
}else{
this.nextElementSibling.value--;
}
compute();
}
}
// 给删除按钮添加点击事件
var del=document.getElementsByClassName('del')
for(var m=0;m<del.length;m++){
del[m].onclick=function(){
if(confirm('确认删除吗')){
this.parentNode.parentNode.remove();
}else if(del[m].length==0){
quan.checked=false;
}
fn();
compute();
if(del.length==0){
quan.checked=false;
}
}
}
// 封装计算小计
function compute(){
//拿到每一行
var leng=document.querySelectorAll('tbody>tr');
//声明一个存小计的变量
var subtotal=0;
//声明一个计件变量
var count=0;
//声明一个存总价的变量
var sum=0;
//获取合计的变量
var heji =document.getElementsByClassName('heji')[0];
//获取计件的变量
var piece=document.querySelector('.piece');
// 循环所有的行
for(var i=0;i<leng.length;i++){
// 获取到单价里面的每一项内容
var danjia=leng[i].querySelector('.danjia').innerHTML.replace('元','');
// 获取到value里面的值
var zhi=leng[i].querySelector('.zhi').value;
// 获取到小计里面的内容
var sub = leng[i].querySelector('.sub');
// 只有每行的复选框选中才会执行以下代码
if(son[i].checked==true){
// 小计=单价*数量
subtotal=parseFloat(danjia*10*zhi)/10
sub.innerHTML=subtotal+'元';
//计算合计
sum+=subtotal;
heji.innerHTML=sum;
//计算计件
count+=Number(zhi);
piece.innerHTML=count;
}
}
//在没有商品的情况把小计和总价赋值为0
if(leng.length==0){
heji.innerHTML=0;
piece.innerHTML=0;
}
}
}//点击添加商品事件
}