要求
1.点击数量加减按钮,可自动更改对应的小计,总数,总计
2.点击删除按钮,可删除购物车的对应商品
3.添加菜单里的商品,购物车已有的在原基础上增加商品数量;没有的在购物车增加该商品
4.添加的商品满足原有购物车的所有功能
代码
CSS
table {
width: 50%;
position: relative;
margin: 30px auto;
border-collapse: collapse;
border: 1px solid gray;
}
th {
background-color: palegreen;
height: 50px;
margin: 0 auto;
border: 1px solid gray;
}
tr {
height: 50px;
margin: 0 auto;
text-align: center;
}
td {
border: 1px solid gray;
}
HTML
<table id="cart">
<tr>
<th>商品名称</th>
<th>数量</th>
<th>单价</th>
<th>小计</th>
<th>操作</th>
</tr>
<tr>
<td>烧煎饼</td>
<td>
<button>-</button>
<span class="goods-num">0</span>
<button>+</button>
</td>
<td>
单价:<span class="goods-unit-price">2</span>
</td>
<td>
小计:<span class="subtotal">0</span>
</td>
<td>
操作:<input class="del" type="button" value="删除">
</td>
</tr>
<tr>
<td>水煮鱼</td>
<td>
<button>-</button>
<span class="goods-num">0</span>
<button>+</button>
</td>
<td>
单价:<span class="goods-unit-price">15</span>
</td>
<td>
小计:<span class="subtotal">0</span>
</td>
<td>
操作:<input class="del" type="button" value="删除">
</td>
</tr>
<tr>
<td colspan="5">
商品一共 <span class="goods-total-num">0</span> 件;共计花费 <span class="goods-total-price">0</span> 元;
</td>
</tr>
</table>
<table id="menu">
<tr>
<th>商品名称</th>
<th>单价</th>
<th>操作</th>
</tr>
<!-- --------- -->
<tr>
<td>水煮鱼</td>
<td>
单价:<span class="goods-unit-price">15</span>
</td>
<td>
操作:<input class="add" type="button" value="添加">
</td>
</tr>
<!-- ---------- -->
<tr>
<td>炒饼</td>
<td>
单价:<span class="goods-unit-price">8</span>
</td>
<td>
操作:<input class="add" type="button" value="添加">
</td>
</tr>
<tr>
<td>孜然烤肉</td>
<td>
单价:<span class="goods-unit-price">22</span>
</td>
<td>
操作:<input class="add" type="button" value="添加">
</td>
</tr>
</table>
<script src="购物车.js"></script>
<script>
let oBtns = document.getElementsByTagName("button")
let oGoodsNum = document.getElementsByClassName("goods-num")
let oSubtotal = document.getElementsByClassName("subtotal")
let oDelBtn = document.getElementsByClassName("del")
let oAddBtn = document.getElementsByClassName("add")
let oTotalNum = document.getElementsByClassName("goods-total-num")[0]
let oTotalPrice = document.getElementsByClassName("goods-total-price")[0]
new Cart(oBtns, oGoodsNum, oSubtotal, oDelBtn, oAddBtn, oTotalNum, oTotalPrice)
</script>
JavaScript
class Cart {
// oBtns:-和+两个按钮
// oGoodsNum:数量
// osubtotal:小计
// oDelBtn:删除按钮
// oAddBtn:添加按钮
// oTotalNum:总数
// oTotalPrice:总价
constructor(oBtns, oGoodsNum, oSubtotal, oDelBtn, oAddBtn, oTotalNum, oTotalPrice) {
this.oBtns = oBtns
this.oGoodsNum = oGoodsNum
this.oSubtotal = oSubtotal
this.oDelBtn = oDelBtn
this.oAddBtn = oAddBtn
this.oTotalNum = oTotalNum
this.oTotalPrice = oTotalPrice
// 调用事件绑定(推荐在内部调用)
this.eventBind()
}
// 更新总数和总价
updateTotalNumAndPrice() {
// 先定义数量相加的和
let totalNum = 0
// 遍历goods-num数量
for (let i = 0; i < this.oGoodsNum.length; i++) {
// 将遍历的每个数量相加,数组的值是字符串格式,需要运用隐式转换为数值类型
totalNum += this.oGoodsNum[i].innerHTML / 1
}
// 总数=相加总计
this.oTotalNum.innerHTML = totalNum
// 先定义价格小计相加的和
let totalPrice = 0
// 遍历subtotal小计
for (let i = 0; i < this.oSubtotal.length; i++) {
// 将遍历的每个小计相加
totalPrice += this.oSubtotal[i].innerHTML / 1
}
// 总数=相加总计
this.oTotalPrice.innerHTML = totalPrice
}
// 数量增加按钮
addNum(btn) {
//1.修改num 完成
//2.修改小计
//3.修改总数 完成
//4.修改总价 完成
// 获取btn的前面那个数
// previousElementSibling 属性返回指定元素的下一个兄弟元素
let oNum = btn.previousElementSibling
// 点击加号按钮,前面的数加1;获取的值是字符串用加法得先用隐式转换为数值型
oNum.innerHTML = oNum.innerHTML / 1 + 1
// 获取单价(btn的父元素的下一个节点元素的第一个子元素)
// parentNode 属性可返回某节点的父节点
// nextElementSibling 属性返回指定元素之后的下一个兄弟元素
// firstElementChild 属性返回指定元素的第一个子元素
let oUnitPrice = btn.parentNode.nextElementSibling.firstElementChild
// 获取小计(btn的父元素的下一节点的下一节点的第一个子元素)
let oSubtotal = btn.parentNode.nextElementSibling.nextElementSibling.firstElementChild
// 小计=数量*单价
oSubtotal.innerHTML = oNum.innerHTML * oUnitPrice.innerHTML
// 调用更新总计数量和价格
this.updateTotalNumAndPrice()
}
// 数量减少按钮
cutNum(btn) {
// 获取后面的数
let oNum = btn.nextElementSibling
if (oNum.innerHTML > 0) {
// 修改获取的数值,在做减法运算时,可直接当做隐式转换,则不用专门去除以1来进行再次隐式转换
oNum.innerHTML = oNum.innerHTML - 1
let oUnitPrice = btn.parentNode.nextElementSibling.firstElementChild
let oSubtotal = btn.parentNode.nextElementSibling.nextElementSibling.firstElementChild
oSubtotal.innerHTML = oNum.innerHTML * oUnitPrice.innerHTML
this.updateTotalNumAndPrice()
}
}
// 删除商品
delGoods(btn) {
// 点击删除按钮时,将删除整一行的货物,找到按钮的的上一级直到要删除的元素
// btn的父元素的父元素tr整个删除,获取
let oTr = btn.parentNode.parentNode
// 删除获取到的内容
oTr.remove()
// 调用更新总计数量和价格
this.updateTotalNumAndPrice()
}
// 从菜单添加商品
addGoods() {
// 获取cart表格
let oCart = document.getElementById("cart")
// 获取购物车的第一个子元素的所有子元素tr
let oCartTr = oCart.firstElementChild.children
// 目标元素赋值为false
let flag = false
let that = this
// 遍历添加按钮
for (let i = 0; i < this.oAddBtn.length; i++) {
// 获取菜单的商品名
let oMenuGoodsName = this.oAddBtn[i].parentNode.previousElementSibling.previousElementSibling
// 点击某个添加按钮时
this.oAddBtn[i].onclick = function () {
// 遍历购物车的第一个子元素的所有子元素tr
for (let j = 0; j < oCartTr.length; j++) {
// 判断菜单中有无该商品,有商品数量加1;无则将商品添加到购物车
// 购物车子元素的第一个元素内容 == 菜单的第一个元素内容(商品名称)
if (oCartTr[j].children[0].innerHTML == oMenuGoodsName.innerHTML) {
// 获取数量
let oNum = oCartTr[j].children[1].children[1]
// 购物车数量加1
oNum.innerHTML = oNum.innerHTML / 1 + 1
// 获取单价
let oUnitPrice = oCartTr[j].children[2].firstElementChild
// 获取总计
let oSubtotal = oCartTr[j].children[3]
// 总计=数量*单价
oSubtotal.innerHTML = `小计:<span class="subtotal">${oNum.innerHTML * oUnitPrice.innerHTML}</span>`
that.updateTotalNumAndPrice()
flag = false
break
} else {
flag = true
}
}
// 如果没有这个商品
if (flag) {
let tr = document.createElement("tr")
tr.innerHTML =
`<tr>
<td>${this.parentNode.previousElementSibling.previousElementSibling.innerHTML}</td>
<td>
<button>-</button>
<span class="goods-num">1</span>
<button>+</button>
</td>
<td>
单价:<span class="goods-unit-price">${this.parentNode.previousElementSibling.lastElementChild.innerHTML}</span>
</td>
<td>
小计:<span class="subtotal">${this.parentNode.previousElementSibling.lastElementChild.innerHTML}</span>
</td>
<td>
操作:<input class="del" type="button" value="删除">
</td>
</tr>`
oCart.firstElementChild.insertBefore(tr, oCart.firstElementChild.lastElementChild)
that.eventBind()
that.updateTotalNumAndPrice()
}
}
}
}
// 事件绑定
eventBind() {
// 设定一个事件的this值
let that = this
// 遍历按钮(button)
for (let i = 0; i < this.oBtns.length; i++) {
// 加号按钮(根据布局设置的加号按钮为偶数位)
if (i % 2) {
// 暂时性死区
// 点击这个按钮时,添加调用增加货物
this.oBtns[i].onclick = function () {
that.addNum(this)
}
} else {
// 否则调用减少货物
this.oBtns[i].onclick = function () {
that.cutNum(this)
}
}
}
// 遍历按钮(input)
for (let i = 0; i < this.oDelBtn.length; i++) {
// 点击哪个删除按钮,整行菜单内容一起删除
this.oDelBtn[i].onclick = function () {
that.delGoods(this)
}
}
this.addGoods()
}
}