js实现购物车功能
将数据渲染到页面上
然后先将格式写出来,分析得出是由一个tr包4个td组成的,将表头用thead包起来,后面写tbody将内容包起来后面的两个td内分别包了两个按钮,最后面有3个输入框和2个按钮(确认和取消),样式要写为display:none
然后将数据以数组包对象的形式写在json文件内
[{
"id": "1",
"name": "包子",
"price": "2",
"num": "0"
},
{
"id": "2",
"name": "油条",
"price": "3",
"num": "0"
},
{
"id": "3",
"name": "鸡蛋",
"price": "1.5",
"num": "0"
},
{
"id": "4",
"name": "胡辣汤",
"price": "3",
"num": "0"
},
{
"id": "5",
"name": "小米粥",
"price": "1",
"num": "0"
}
]
我们先将要用到的都获取过来,并且将data的作用域提到全局,并且每次添加的时候都是在id后面添加,设置一个最大的id为数据内在最大的id(确保唯一性),ee
let data;
let max_ID;
// 获取弹窗
let alerts = document.getElementById('ti_body');
// 获取删除
let dlt = document.getElementsByClassName('delete');
// 获取数量+
let append = document.getElementsByClassName('append');
// 获取数量-
let reduce = document.getElementsByClassName('reduce');
// 获取tbody
let tbody = document.getElementById('goods');
// 获取三个添加时的输入框
let addname = document.getElementById('name');
let addprice = document.getElementById('price');
let addnum = document.getElementById('number');
// 获取三个编辑是的输入框
let addnames = document.getElementById('names');
let addprices = document.getElementById('prices');
let addnums = document.getElementById('numbers');
// 获取添加按钮
let add = document.getElementsByClassName('add')[0];
// 添加输入框区域
let content = document.getElementsByClassName('content')[0];
// 编辑输入框区域
let contents = document.getElementsByClassName('contents')[0];
// 取消按钮
let off = document.getElementsByClassName('off')[0];
// 获取商品数量
let how = document.getElementsByClassName('how')[0];
// 总价框
let total = document.getElementById('total');
// 总数量框
let tot = document.getElementById('tot');
// 获取json文件
let xhr = new XMLHttpRequest();
xhr.open('get', 'js/new_file.json', true);
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
let text = xhr.responseText;
console.log(text);
data = JSON.parse(text);
max_ID = data[data.length - 1].id
console.log(max_ID);
console.log(data);
render(data);
}
};
将数据渲染到页面上,以字符串拼接的形式
function render(data) {
let str = ``;
let num = 0;
let count = 0;
for (let i = 0; i < data.length; i++) {
str += `<tr>
<td>${data[i].name}</td>
<td>${data[i].price}</td>
<td><button class="reduce" onclick="cut_num(${i})">-</button> <span class="how">${data[i].num}</span> <button class="append" onclick="add_num(${i})">+</button>
</td>
<td><button class="edit" onclick="edit(${i})">编辑</button><button class="delete" onclick="del(${i})" >删除</button></td>
</tr>`;
num += data[i].num * 1;
count += data[i].num * data[i].price;
}
total.innerHTML = count;
tot.innerHTML = num;
tbody.innerHTML = str;
};
然后给按钮+绑定点击事件,当每次点击时,对应的下标index的num++
function add_num(index) {
data[index].num++;
render(data);
};
然后给按钮-绑定点击事件,当每次点击时,对应的下标index的num--
function cut_num(index) {
if (data[index].num > 0) {
data[index].num--;
render(data);
};
};
点击删除时,运用splice的方法,从对应下标删除,并且删除一个
function del(index) {
data.splice(index, 1);
render(data);
};
点击添加的时候,应该先将隐藏的输入框和按钮显示出来,并且清空里面的值
function add_show() {
content.style.display = 'block'
addname.value = '';
addprice.value = '';
addnum.value = '';
};
当点击取消时再将他们隐藏起来
function add_off() {
content.style.display = 'none'
}
接下来写确定添加的点击事件,按实际情况来说的话,我们商品名称不能为空;并且商品价格不能为空,不能小于0;商品数量不能为空,不能小于0,商品的价格不能为空,不能小于0,并且是整数,如果不符合条件的话弹出弹窗提示用户,所以我们的添加的点击事件要写判断,并且添加时使最大的id++,渲染完成后再让输入框和按钮隐藏
判断如下:
// 添加确定
function add_confirm() {
// 判断,如果第一个name输入框内为空返回弹窗
if (addname.value == "") {
alerts.style.top = `0`
alerts.innerHTML = `输入无效,请输入一个商品!`
setTimeout(function() {
alerts.style.top = `-10%`
}, 3000)
// 如果第二个为空或者数字小于0时返回弹窗
} else if (addprice.value == "" || addprice.value < 0) {
alerts.style.top = `0`
alerts.innerHTML = `输入无效,请输入一个数字!`
setTimeout(function() {
alerts.style.top = `-10%`
}, 3000)
// 如果数量为空,并且小于0,并且当他不为整数时返回弹窗
} else if (addnum.value == "" || addnum.value < 0 || addnum.value % 1 != 0) {
alerts.style.top = `0`
alerts.innerHTML = `输入无效,请输入一个数字!`
setTimeout(function() {
alerts.style.top = `-10%`
}, 3000)
} else {
max_ID++;
data.push({
id: max_ID,
name: addname.value,
price: addprice.value,
num: addnum.value
})
console.log(data);
render(data);
content.style.display = 'none';
}
}
编辑按钮点击的时候,我们应该获取到他在哪一行,并且获取哪一行的数据,将数据传递到输入框内,并且将这个id存起来
function edit(i) {
addnames.value = data[i].name;
addprices.value = data[i].price;
addnums.value = data[i].num;
sessionStorage.setItem('edit_id', data[i].id)
contents.style.display = 'block';
};
当我们编辑点确定的时候也需要判断,判断条件和上面的相同,如果所有的格式没有问题,那么将json中的id遍历一下,看看能不能找到和上面我们存的id相同,相同的话,再将内容进行替换并且重新渲染就好了
还有一种情况,我们点编辑后将这一条数据删除了,那么我们应该返回编辑失败
这种就先声明一个变量为false,当他在数据内能找到找个id将他变为true,这样就可以显示渲染,如果找不到那么就还是false,下面判断,如果当这个变量为false时,那么就返回弹窗,最后渲染时再将输入框隐藏即可
// 编辑判断
function add_confirms() {
if (addnames.value == "") {
alerts.style.top = `0`
alerts.innerHTML = `输入无效,请输入一个商品!`
setTimeout(function() {
alerts.style.top = `-10%`
}, 3000)
} else if (addprices.value == "" || addprices.value < 0) {
alerts.style.top = `0`
alerts.innerHTML = `输入无效,请输入一个数字!`
setTimeout(function() {
alerts.style.top = `-10%`
}, 3000)
} else if (addnums.value == "" || addnums.value < 0 || addnums.value % 1 != 0) {
alerts.style.top = `0`
alerts.innerHTML = `输入无效,请输入一个数字!`
setTimeout(function() {
alerts.style.top = `-10%`
}, 3000)
} else {
let a = false;
for (let i = 0; i < data.length; i++) {
if (data[i].id == sessionStorage.getItem('edit_id')) {
data[i].name = addnames.value;
data[i].price = addprices.value;
data[i].num = addnums.value;
a = true;
break;
}
}
if (a == false) {
alerts.style.top = `0`
alerts.innerHTML = `编辑失败!`
setTimeout(function() {
alerts.style.top = `-10%`
}, 3000)
}
contents.style.display = 'none';
render(data);
}
};
下面是全部的代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
</head>
<style>
#ti_body {
top: -10%;
left: 45vw;
width: auto;
height: 40px;
background-color: red;
color: white;
text-align: center;
line-height: 40px;
padding: 3px 30px;
border-radius: 0.25rem;
position: fixed;
z-index: 999;
display: flex;
justify-content: space-between;
}
</style>
<body>
<table border="1px" cellpadding="10px" style="border-collapse: collapse;">
<thead>
<tr>
<th>商品名称</th>
<th>商品价格(单位为元)</th>
<th>商品数量</th>
<th>操作</th>
</tr>
</thead>
<tbody id="goods" style="text-align: center;">
<tr>
<td></td>
<td>28</td>
<td><button class="reduce">-</button> <span class="how">0</span> <button class="append">+</button>
</td>
<td><button class="edit">编辑</button><button class="delete">删除</button></td>
</tr>
</tbody>
<footer>
<tr style="text-align: center;">
<td>总价:</td>
<td id="total"></td>
<td>总数量:</td>
<td id="tot"></td>
</tr>
</footer>
</table>
<button class="add" onclick="add_show()">添加</button>
<div style="display: none;" class="content">
<input type="text" placeholder="请输入商品名称" id="name" />
<input type="number" placeholder="请输入商品价格" id="price" />
<input type="number" placeholder="请输入商品数量" id="number" />
<br />
<button onclick="add_confirm()">确认</button>
<button class="off" onclick="add_off()">取消</button>
</div>
<div style="display: none;" class="contents">
<input type="text" placeholder="请输入商品名称" id="names" />
<input type="number" placeholder="请输入商品价格" id="prices" />
<input type="number" placeholder="请输入商品数量" id="numbers" />
<br />
<button onclick="add_confirms()">确认</button>
<button class="off" onclick="add_offs()">取消</button>
</div>
<div id="ti_body">
<div id="ti_content">
成功提示的文案
</div>
<div id="over" onclick="cancel()">×</div>
</div>
<script>
let data;
let max_ID;
// 获取弹窗
let alerts = document.getElementById('ti_body');
// 获取删除
let dlt = document.getElementsByClassName('delete');
// 获取数量+
let append = document.getElementsByClassName('append');
// 获取数量-
let reduce = document.getElementsByClassName('reduce');
// 获取tbody
let tbody = document.getElementById('goods');
// 获取三个添加时的输入框
let addname = document.getElementById('name');
let addprice = document.getElementById('price');
let addnum = document.getElementById('number');
// 获取三个编辑是的输入框
let addnames = document.getElementById('names');
let addprices = document.getElementById('prices');
let addnums = document.getElementById('numbers');
// 获取添加按钮
let add = document.getElementsByClassName('add')[0];
// 添加输入框区域
let content = document.getElementsByClassName('content')[0];
// 编辑输入框区域
let contents = document.getElementsByClassName('contents')[0];
// 取消按钮
let off = document.getElementsByClassName('off')[0];
// 获取商品数量
let how = document.getElementsByClassName('how')[0];
// 总价框
let total = document.getElementById('total');
// 总数量框
let tot = document.getElementById('tot');
// 获取json文件
let xhr = new XMLHttpRequest();
xhr.open('get', 'js/new_file.json', true);
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
let text = xhr.responseText;
console.log(text);
data = JSON.parse(text);
max_ID = data[data.length - 1].id
console.log(max_ID);
console.log(data);
render(data);
}
};
// 渲染函数
function render(data) {
let str = ``;
let num = 0;
let count = 0;
for (let i = 0; i < data.length; i++) {
str += `<tr>
<td>${data[i].name}</td>
<td>${data[i].price}</td>
<td><button class="reduce" onclick="cut_num(${i})">-</button> <span class="how">${data[i].num}</span> <button class="append" onclick="add_num(${i})">+</button>
</td>
<td><button class="edit" onclick="edit(${i})">编辑</button><button class="delete" onclick="del(${i})" >删除</button></td>
</tr>`;
num += data[i].num * 1;
count += data[i].num * data[i].price;
}
total.innerHTML = count;
tot.innerHTML = num;
tbody.innerHTML = str;
};
console.log(max_ID);
// 添加次数
function add_num(index) {
data[index].num++;
render(data);
};
// 减少
function cut_num(index) {
if (data[index].num > 0) {
data[index].num--;
render(data);
};
};
// 删除
function del(index) {
data.splice(index, 1);
render(data);
};
// 添加显示
function add_show() {
content.style.display = 'block'
addname.value = '';
addprice.value = '';
addnum.value = '';
};
// 取消
function add_off() {
content.style.display = 'none'
}
function add_offs() {
contents.style.display = 'none'
}
// 添加确定
function add_confirm() {
// 判断,如果第一个name输入框内为空返回弹窗
if (addname.value == "") {
alerts.style.top = `0`
alerts.innerHTML = `输入无效,请输入一个商品!`
setTimeout(function() {
alerts.style.top = `-10%`
}, 3000)
// 如果第二个为空或者数字小于0时返回弹窗
} else if (addprice.value == "" || addprice.value < 0) {
alerts.style.top = `0`
alerts.innerHTML = `输入无效,请输入一个数字!`
setTimeout(function() {
alerts.style.top = `-10%`
}, 3000)
// 如果数量为空,并且小于0,并且当他不为整数时返回弹窗
} else if (addnum.value == "" || addnum.value < 0 || addnum.value % 1 != 0) {
alerts.style.top = `0`
alerts.innerHTML = `输入无效,请输入一个数字!`
setTimeout(function() {
alerts.style.top = `-10%`
}, 3000)
} else {
max_ID++;
data.push({
id: max_ID,
name: addname.value,
price: addprice.value,
num: addnum.value
})
console.log(data);
render(data);
content.style.display = 'none';
}
}
// 编辑效果
function edit(i) {
addnames.value = data[i].name;
addprices.value = data[i].price;
addnums.value = data[i].num;
sessionStorage.setItem('edit_id', data[i].id)
contents.style.display = 'block';
};
// 编辑判断
function add_confirms() {
if (addnames.value == "") {
alerts.style.top = `0`
alerts.innerHTML = `输入无效,请输入一个商品!`
setTimeout(function() {
alerts.style.top = `-10%`
}, 3000)
} else if (addprices.value == "" || addprices.value < 0) {
alerts.style.top = `0`
alerts.innerHTML = `输入无效,请输入一个数字!`
setTimeout(function() {
alerts.style.top = `-10%`
}, 3000)
} else if (addnums.value == "" || addnums.value < 0 || addnums.value % 1 != 0) {
alerts.style.top = `0`
alerts.innerHTML = `输入无效,请输入一个数字!`
setTimeout(function() {
alerts.style.top = `-10%`
}, 3000)
} else {
let a = false;
for (let i = 0; i < data.length; i++) {
if (data[i].id == sessionStorage.getItem('edit_id')) {
data[i].name = addnames.value;
data[i].price = addprices.value;
data[i].num = addnums.value;
a = true;
break;
}
}
if (a == false) {
alerts.style.top = `0`
alerts.innerHTML = `编辑失败!`
setTimeout(function() {
alerts.style.top = `-10%`
}, 3000)
}
contents.style.display = 'none';
render(data);
}
};
</script>
</body>
</html>