这算一次复盘吧,接到的一个需求:前后分离,前端走完一个简单购物流程,然后最后将数据提交给后台。
第一次写的时候写得挺混乱的,埋了不少坑,同事看不下去了,帮忙填了一次坑。o(╥﹏╥)o(真的不想坑人)
后面自己整理了下思路,私下自己在重新写了一遍,这里记录一下.
这次主要收获:
1. 前后分离思想
2. cookie的应用
3. 改掉混乱的面条式代码,提升复用率,模块化编程
需求分析
- 首先,一共四个页面:
首页——>产品列表页——>购物车页面——>结算页面 - 需要实现的功能点:
- 在首页和产品列表页点击某产品可以加入购物车
- 如果该产品已经在购物车内则不能重复加入
- 每个页面头部购物车数量更新
- 在购物车页面时历遍出在购物车中的产品
- 计算以及显示 产品总价、运费、以及订单总价(运费+总价)
- 进入结算页面历遍出需要结算的产品和单价,以及更新产品总价,和订单总价(加运费);
- 加急运费,如果勾选加急运费则加上运费,如果不勾选则恢复。
- 如果所购买的产品中有Monthy产品,则显示相应协议,如果没有则不显示。
- 在结算页面提交时需要校验信息。
具体实现
1.建立一个JSON,存放产品的数据信息,如:
var productInfo = {
"product-des_1": "A bottle of drink", //产品名字
"product-des_2": "2 bottles of drinks",
"product-des_3": "3 bottles of drinks",
"product-des_4": "4 bottles of drinks",
"product-des_5": "5 bottles of drinks",
"product-des_6": "Buy one bottle a month"
"product-price_1": 9.99, //对应的产品价格
"product-price_2": 19.99,
"product-price_3": 29.99,
"product-price_4": 39.99,
"product-price_5": 49.99,
"shipping-price" : 8.00, //加急运费
"shipping-fee": 0 //运费
};
2.加入购物车
当某产品点击加入购物车按钮时,传入对应产品的id,如:
<a class="btn" onclick="addCart(3);">ADD TO CART</a>
在接收这个id后,需要实现几个点:
- 创建一个对象作为产品,对象key值有[产品ID]、[产品名字]、[产品价格]、[是否是monthy产品]。
- 判断是否已经存有cookie,如果没有,则建立一个新数组,并push入新加的产品,并存储入cookie;
- 如果已有cookie,则取出cookie赋值给一个变量,历遍该变量。这里需要实现两个功能点:
- 判断这个产品是否加入过购物车
- 在历遍的同时,加出所有产品的总价。
- 如果购物车内没有此产品,则可以将改产品push入数组,并更新总价,然后存入cookie。
- 调用修改购物车个数。
function addCart(productId){
var productDes = "product-des_" + productId;
var productPri = "product-price_" + productId;
var proName = productInfo[productDes];
var pPrice = productInfo[productPri];
var products = {};
products.id = productId;
products.name = proName;
products.price = pPrice;
//判断是否是Monthy产品
if(proName.indexOf('month') != -1){
products.auto = 1;
}
if(typeof $.cookie('productList') == 'undefined'){
var proList = [];
proList.push(products);
$.cookie('productList', JSON.stringify(proList));
$.cookie('proTotal', pPrice.toFixed(2));
}else{
var proList = JSON.parse($.cookie('productList'));
var isAdd = true;
var pTotal = 0;
for(let i=0; i<proList.length; i++){
let p = proList[i];
if(p.id == productId){
isAdd = false;
}
pTotal = pTotal + p.price;
}
if(isAdd){
proList.push(products);
pTotal = pTotal + products.price;
$.cookie('productList', JSON.stringify(proList));
$.cookie('proTotal', pTotal.toFixed(2));
}
}
//更新购物车数量
innerCartCount();
}
3.修改购物车个数
html页面上:
<span>Cart(<b id="cartNum">0</b>)</span>
首先需要判断页面上是否有这个元素(以防在其他页面调用的时候报错),并且需要判断是否存储了产品cookie。
取出cookie赋值给变量,读取该变量的个数,并更改页面上的数量。
function innerCartCount(){
var cartNum = document.getElementById('cartNum');
if(cartNum != null && cartNum != ''){
if(typeof $.cookie('productList') != 'undefined'){
var proList = JSON.parse($.cookie('productList'));
var count = proList.length;
cartNum.innerHTML = count;
}
}
}
在这里需要注意一定,除了加入购物车时调用外,也需要在外面调用这个函数,解决页面一刷新,数量就清零的尴尬问题。
4.购物车页面
历遍出所有产品(产品名字、价格、以及删除按钮)
function innerCartBodyHtml(){
var cartBody = document.getElementById('cartBody');
if(cartBody != null && cartBody != ''){
if(typeof $.cookie('productList') != 'undefined'){
var proList = JSON.parse($.cookie('productList'));
var html = '';
for(let i=0; i<proList.length; i++){
let p = proList[i];
html = html + `
<tr>
<td>${p.name}</td>
<td>${p.price}</td>
<td class='remove'>
<a class="btn btn-default" onclick="removeCart(${p.id},this)">remove</a>
</td>
</tr>
`
}
cartBody.innerHTML = html;
}
}
}
更新页面产品总价、运费、以及订单总价。
function innerPrice(){
if(typeof $.cookie('proTotal') != 'undefined'){
var proTotal = Number($.cookie('proTotal'));
//产品总价
var subTotal = document.getElementById('subTotal');
if(subTotal != null && subTotal != ''){
subTotal.innerHTML = '$' + proTotal.toFixed(2);
}
//运费
var shipFee = document.getElementById('shipFee');
if(shipFee != null && shipFee != ''){
var shipFeePrice = Number(productInfo['shipping-fee']);
shipFee.innerHTML = shipFeePrice.toFixed(2);
}
//订单总价
var orderTotal = document.getElementById('orderTotal');
if(orderTotal != null && orderTotal != ''){
var oTotal = proTotal + shipFeePrice;
$.cookie('orderTotal',oTotal.toFixed(2));
orderTotal.innerHTML = '$' + oTotal.toFixed(2);
}
}
}
删除购物车产品:
- 点击删除按钮时,传入该产品id以及this。
- 取出cookie以及总价,赋值给个数组,并历遍该数组,这里需要实现2点:
- 如果产品id与传入的id相同,则从数组中删除该元素。
- 总价减去改产品价格,更新cookie。
- 删除页面元素,更新页面价格,更新购物车个数。
function removeCart(productId, obj){
if(typeof $.cookie('productList') != 'undefined'){
var proList = JSON.parse($.cookie('productList'));
var pTotal = Number($.cookie('proTotal'));
for(let i=0; i<proList.length; i++){
let p = proList[i];
if(p.id == productId){
proList.splice(i,1);
pTotal = pTotal - p.price;
$.cookie('productList', JSON.stringify(proList));
$.cookie('proTotal', pTotal.toFixed(2));
}
}
//删除页面元素
var cartTr = obj.parentNode.parentNode;
var cartTbody = cartTr.parentNode;
cartTbody.removeChild(cartTr);
//更新价格
innerPrice();
//更新购物车数量
innerCartCount();
}
}
5.结算页面
结算页面需要历遍出需要结算的产品,和购物车的历遍差不多,但是这里不能删除,只要产品名和价格。
function innerCheckoutProductListHtml(){
var checkoutProList = document.getElementById('checkoutProductList');
if(checkoutProList != null && checkoutProList != ''){
if(typeof $.cookie('productList') != 'undefined'){
var proList = JSON.parse($.cookie('productList'));
var html = '';
for(let i=0; i<proList.length; i++){
let p = proList[i];
html = html + `
<li>
<span class="pull-left">${p.name}</span>
<span class="pull-right">${p.price}</span>
</li>
`
}
checkoutProList.innerHTML = html;
}
}
}
更新页面运费:
这里主要是将页面显示运费处写活,至于产品总价和订单已经写过,结算页面只需要加上对应id即可,不用重复写。
function getShippingPrice(){
var shippingPrice = document.getElementById('shippingPrice');
if(shippingPrice != null && shippingPrice != ''){
var shipPrice = Number(productInfo['shipping-price']);
shippingPrice.innerHTML = '$' + shipPrice;
}
}
是否勾选加急运费
function fastshippingClick(){
var fastShipping = document.getElementById('fastshipping');
var orderTotal = document.getElementById('orderTotal');
var ProtectPack = document.getElementById('ProtectPack');
if(orderTotal != null && orderTotal != ''){
if(typeof $.cookie('orderTotal') != 'undefined'){
var oTotal = Number($.cookie('orderTotal'));
if(fastShipping.checked){
oTotal = oTotal + Number(productInfo['shipping-price']);
orderTotal.innerHTML = '$' + oTotal.toFixed(2);
ProtectPack.value = 1;
}else{
orderTotal.innerHTML = '$' + oTotal.toFixed(2);
ProtectPack.value = 0;
}
}
}
}
是否存在Monthy产品,如果存在,显示出对应的条款说明,不存在则隐藏
function checkSubs(){
var chkSubs = document.getElementById('chk_subs');
var proInfo = document.getElementById('proinfo');
if(chkSubs != null && chkSubs != '' && proInfo != null && proInfo != ''){
if(typeof $.cookie('productList') != 'undefined'){
var html = '';
var isShow = false;
var proList = JSON.parse($.cookie('productList'));
for(let i=0; i<proList.length; i++){
let p = proList[i];
if(p.auto == 1){
isShow = true;
html = html + `<li><b>${p.price} for Level 8 ${p.name}</b></li>`;
}
}
proInfo.innerHTML = html;
//如果又monthy产品显示条款
if(isShow){
chkSubs.style.display = 'block';
}
}
}
}
总结:
一个简单的购物流程,其实主要的点就是在购物车添加删除以及数据的存取上。
动手写代码前需要理清思路,思路清晰了,一个小点一个小点的写下来就会顺利很多,并且会避免遗漏。
网友评论