代码改变世界

【原创】JS+COOKIES实现健壮的购物车!

2007-11-28 16:41  码农.KEN  阅读(5277)  评论(37编辑  收藏  举报
近日正在写个商城系统,打算自己开个服装店的,o(∩_∩)o...哈哈

      大家都知道商城系统中是离不开购物车的,据观察,网上大多数商城程序的购物车都是采用的一种比较简单的存储方式来实现购物车,那就是把选中了的ID直接拼接起来。这种做法当然在需求不高的情况下足矣,可是想要拥有一个更健壮的购物车的话,却不能满足了。

      我的方法是将购物车内商品的几个基本必要属性都要存储起来,如:品名、数量、当前价格、图片地址等等。

这些属性我们怎么来存呢?
         方法不是唯一的,数据库、SESSION、Cookies……,可能大部分朋友会选用数据库,我选用的是COOKIES,因为购物车仅仅用来为用户购买商品提供个便利的集中容器,既然是临时用的,何必要劳驾数据库呢?我写程序的原则是:要尽可能的给服务器减压。用COOKIES来存储,就是存储在客户端。

      存储我们选用了COOKIES,那么接下来就应该是如何来操作这个"小甜饼"了.
如何来操作COOKIES,实现购物车呢?
         还是那句话,尽可能给服务器减压,既然存储用了客户端的东东,那么我们操作当然也可以用客户端的东东啊,那就是JAVASCRIPT了,嗯,JS是可以直接读写COOKIES的。以下是JS读写COOKIES的代码:
// JScript 文件
/*
by 码农.KEN (2007-11-9)
*/

var cookie={  
//读取COOKIES,n为COOKIE名
  Get:function(n){  
    
var re=new RegExp(n+'=([^;]*);?','gi');  
    
var r=re.exec(document.cookie)||[];  
    
return (r.length>1?r[1]:null)  
  }
,
    Get1:
function(n){  
    
var re=new RegExp(n+'=([^;]*);?','gi');  
    
var r=re.exec(document.cookie)||[];  
    
return unescape(r.length>1?r[1]:null)  
  }
,
  
//写入COOKIES,n为Cookie名,v为value
  Set:function(n,v,e,p,d,s)
    
var t=new Date;  
    
if(e){  
  
// 8.64e7 一天  3.6e6 一小时
  t.setTime(t.getTime() + (e*3.6e6));
      
     }

    document.cookie
=n+'='+v+'; '+(!e?'':'; expires='+t.toUTCString())+(!p?'':'; path='+p)+(!d?'':'; domain='+d)+(!s?'':'; secure')  // Set cookie
  }
,
    Set1:
function(n,v,e,p,d,s)
    
var t=new Date;  
    
if(e){  
  
// 8.64e7 一天  3.6e6 一小时
  t.setTime(t.getTime() + (e*8.64e7));
      
     }

    document.cookie
=n+'='+escape(v)+'; '+(!e?'':'; expires='+t.toUTCString())+(!p?'':'; path='+p)+(!d?'':'; domain='+d)+(!s?'':'; secure')  // Set cookie
  }
,
  Del:
function(n,p,d){  
    
var t=cookie.Get(n);  
    document.cookie
=n+'='+(!p?'':'; path='+p)+(!d?'':'; domain='+d)+'; expires=Thu, 01-Jan-70 00:00:01 GMT';  
    
return t  
  }

}
;
//var TotalPro = cookie.Get("TotalPro"); //当前车内含有商品的总数
下面该说说JS具体如何来操作购物车了,在这里,购物车需要的操作有:增加商品、修改商品、删除商品。
这些操作偶就直接贴代码了,都做了注释的,如果有不明之处可以回帖,我尽力作答。

说明下:如果JS本身具有能直接操作带有子键的COOKIES的话,那完全没有必要写出下面那么多行的代码了!
var Common = {
             
             
//移除数组中指定项
             
            delArr:
function(ar,n) {  //n表示第几项,从0开始算起。
             if(n<0)  //如果n<0,则不进行任何操作。
                 return ar;
             
else
                 
return ar.slice(0,n).concat(ar.slice(n+1,ar.length));
             }
,
             
             
//添加至购物车
             intoCar:function(proid,quantity,proname,imgurl,_price) {
             
if(proid != "" && proname != ""{
             
var ProIDList = cookie.Get("carList"); //车内商品ID列表
             if(ProIDList!=null && ProIDList!="" && ProIDList!="null")
             
{
                  
if(Common.hasOne(proid))
                  
{
                     ProIDList 
+= "&"+proid+"="+proid+"|"+quantity+"|"+escape(proname)+"|"+escape(imgurl)+"|"+_price;
                     cookie.Set(
"carList",ProIDList,2,"/");//更新购物车清单
                     TotalPro = cookie.Get("TotalPro"); //当前车内含有商品的总数
                      TotalPro++//总数+1
                     cookie.Set("TotalPro",TotalPro,2,"/");
                  }

                  
else
                  
{
                  alert(
"购物车中已含有此商品");
                  }

             }

             
else {
             
                  ProIDList
=proid+"="+proid+"|"+quantity+"|"+escape(proname)+"|"+escape(imgurl)+"|"+_price;
                  cookie.Set(
"carList",ProIDList,2,"/");//更新购物车清单
                      
                  cookie.Set(
"TotalPro",1,2,"/");
             }

             Common.reloadcar();
//更新顶部个数显示
             //alert(ProIDList);
             }

             
             }
,  //添加物品结束
             
             
//重置购物车内个数
             reloadcar:function()
             
{
             
var t=cookie.Get("TotalPro");
             
if(t!=""&&t!="null")
             document.getElementById(
"cart_num").innerText="(" + cookie.Get("TotalPro"+ ")";
             
else
             document.getElementById(
"cart_num").innerText="(0)";
             }
,  //重置结束
             
             
//检验购物车内是否已经含有该商品
             hasOne:function(pid){
             ProIDList 
= cookie.Get("carList"); //车内商品ID列表
                  if(ProIDList.lastIndexOf("&"!= -1){
                      
var arr=ProIDList.split("&");
                      
for(i=0;i<arr.length;i++)
                      
{
                      
//alert(arr.indexOf("="));
                      if(arr.substr(0,arr.indexOf("="))==pid)
                      
{
                      
                         
return false;
                      }

                      }

                  }

                  
else if(ProIDList!="null"&&ProIDList!="")
                  
{
                  
if(ProIDList.substr(0,ProIDList.indexOf("="))==pid)
                  
return false;
                  }

                  
return true;
             }
,  //检测结束
             
             
//移除某商品
             reMoveOne:function(proid){
                  
                  
if(!Common.hasOne(proid)){
                       
if(ProIDList.lastIndexOf("&"!= -1){
                       
var arr=ProIDList.split("&");
                       
for(i=0;i<arr.length;i++){
                            
if(arr.substr(0,arr.indexOf("="))==proid) {
                             
                              
var arr2=Common.delArr(arr,i);
                               
var tempStr=arr2.join("&"); //由数组重组字符串
                               
                               cookie.Set(
"carList",tempStr,2,"/");//更新购物车清单
                               var t=cookie.Get("TotalPro");
                               cookie.Set(
"TotalPro",t-1,2,"/");//更新Cookies中的个数
                              // Common.reloadcar();//更新顶部个数显示
                               return;
                              }

                       }

                       }

                       
else{
                       
                               cookie.Set(
"carList","null");//更新购物车清单
                               var t=cookie.Get("TotalPro");
                               cookie.Set(
"TotalPro",0,2,"/");//更新购物车清单
                              // Common.reloadcar();//更新顶部个数显示
                       }

                  }

             
             }
,   //移除物品结束
             
             
//修改某物品数量
             updateQuantity:function(proid,quantity){
                 ProIDList 
= cookie.Get("carList"); //车内商品ID列表
                 if(ProIDList.lastIndexOf("&"!= -1{
                       
var arr=ProIDList.split("&");
                       
var sub=Common.getSubPlace(ProIDList,proid);//获取该物品在COOKIE数组中的下标位置
                       var arr2=arr[sub].split("|");
                       arr2[
1]=quantity;
                       
var tempStr=arr2.join("|");//由数组重组字符串
                       arr[sub] = tempStr;
                       
var newProList = arr.join("&");//由数组重组字符串
                       cookie.Set("carList",newProList,2,"/");//更新购物车清单
                        //alert(newProList);
                 }

                 
else {
                 
                       
var arr=ProIDList.split("|");
                       arr[
1]=quantity;
                       
var newProList=arr.join("|");
                       cookie.Set(
"carList",newProList,2,"/");//更新购物车清单
                       //alert(newProList);
                 }

             
             
             }
,  //修改物品结束
             
             
//返回指定物品所在数组的下标位置
             getSubPlace:function(list,proid){
                  
var arr=list.split("&");
                       
for(i=0;i<arr.length;i++){
                            
if(arr.substr(0,arr.indexOf("="))==proid) {
                                
return i;
                            }

                       }

                     
             }
 //返回下标结束
        
        
        
        
        
                  
             
             }
;

至此,购物车的核心操作部分已经完毕,接下来就是如何体现出购物车内的东西了!

在这里,我只写出ASP.NET来体现购物车的代码,^_^,因为其他的语言偶也不怎么熟悉。

        如果你已经看明白了上面的购物车添加商品的JS代码,那么你应该知道我们将如何来读取购物车内的物品了。前面我提到过带有子键的COOKIES,大家知道ASP.NET中,COOKIES是可以分组的,结构类似于:
["A1"]["11111"]
["A1"]["22222"]
["A1"]["33333"]
上面的A1是一个COOKIES组,后面的111,222分别是这个组下面的子键,之前我们的JS在增加商品进入COOKIES的时候就是这样来存储的。每个商品的ID作为一个子键,然后商品的其他属性即为该子键的COOKIES值。那么你可能想问:多个属性是怎么存储的呢?很简单,直接把多个属性值用"|"隔开即可。
["carList"]["120"]="充气娃娃|5|500.50|cqww.jpg"  //就类似于这种结构了

以下给出ASP.NET来读取购物车中所有物品的代码,其实就那么一小段:
public ArrayList GetItems()
        
{
            HttpCookie c 
= HttpContext.Current.Request.Cookies["carList"];
           
            ArrayList items 
= new ArrayList();
            
for (int i = 0; i < c.Values.Count; i++)
            
{
                
string[] vals = c.Values.Split('|');
                MY_Shop.Model.CShoppingCartItem item 
= new MY_Shop.Model.CShoppingCartItem();
                item.ProductID 
= int.Parse(vals[0]);
                item.Quantity 
= int.Parse(vals[1]);
                item.ProductName 
= HttpContext.Current.Server.UrlDecode((string)vals[2]);
                item.ImgUrl 
= HttpContext.Current.Server.UrlDecode((string)vals[3]);
                item.Price_s 
= decimal.Parse(vals[4]);
                items.Add(item);
            }

            
return items;
        }


了解三层开发的朋友应该知道,上面代码中的MY_Shop.Model.CShoppingCartItem类实际上就是个实体类。为了不让新手感到迷惑,下面贴出实体类的代码:
Code

OH,全剧终!第一次写技术文章,可能有些潦草,希望能给朋友们一些帮助,如果您有好的意见可以直接回帖提出,但谢绝那些出口成脏的大侠!