商品SKU选择实现效果

8 篇文章 0 订阅

商品SKU选择实现

在客户购买商品的时候,若这个商品存在多种”规格”(SKU),就需要客户手动选择自己想要的哪款。当时并不是每种我们都有库存, 所有就需要提供提供一个筛选功能,当客户选中一个条件的时候,需要设置其他条件中的一些值不可选。 这样就能保证不论客户怎么选择,到最后的选择都是有库存的”规格”(SKU)

开始之前先定义几种术语

属性集: 一个商品全部属性的集合

属性: 商品中的 尺码 颜色 就是两个属性

属性值: 尺码、颜色可有多个值 比如 衣服的尺码:S M XL 衣服的颜色:黑色 白色 蓝色 其中 XL 黑色就是属性值

SKU: Stock Keeping Uint(库存量单位) 由属性值组合而成(这些属性值属于不通的属性)如 一件衣服 (XL,白色) 它能确定商品的 唯一性 ,同一款式的衣服 可能有不通的颜色和大小 ,把颜色大小限制住,就能确定这件‘商品’了。

为了简化 我们虚拟出一个的商品, 下面是它的属性集和SKU:

var keys = {
    'attr1':['10','11'],
    'attr2':['20','21','22','23'],
    'attr3':['30','31','32'],
    'attr4':['40','41']
};
/*num是库存*/
var sku_list=[
    {'attrs':'10|20|30|40','num':120},
    {'attrs':'10|21|30|40','num':10},
    {'attrs':'10|22|30|40','num':28},
    {'attrs':'10|22|31|41','num':220},
    {'attrs':'10|22|32|40','num':130},
    {'attrs':'11|23|32|41','num':120},
    ];    
为选择之前是这种显示状态
attr1  10    11
attr2  20    21   22   23 
attr3  30    31   32 
attr4  40    41 

attr1-attr4中有 2x4x3x2=42种组合,但是有库存的只有上面6种组合

我们要做的就是,在选择某一个属性的时候,把其他为选择的属性中的一些值设置为block(锁定状态) 因为它们和已选属性的组合是没有库存的(有库存的只有上面6种)

比如:
选择 10 和 21后, 有库存的SKU(组合) 只有

{'attrs':'10|21|30|40','num':10},

attr3中的 31   32  以及attr4中的  41  就要设置为block

attr1 *10*   11 
attr2  20   *21*  22   23 
attr3  30   -31- -32-
attr4  40   -41-

总结1:在所有库存组合(sku_list)中筛选出包含选中属性值(10,21)组合(10|21|30|40)未选的属性(attr3、attr4)中的所有属性值若不在这个组合中就设置为block

还有一个问题,在已选属性(attr1,attr2)中 , 我可以把21换成2022; 因为 10|21 10|22 也是一种可行组合(有库存),10|23不可行,所以需要2022也可选,23设置为block

或者21不变,修改attr1中的属性值 11|21 不可行,11设置block。

attr1 *10*  -11-
attr2  20   *21*  22  -23-
attr3  30   -31- -32-
attr4  40   -41-  

总结2: 已选属性 (attr1,attr2) 中任意一个属性(attr1)的属性值(10,11), 若不能和其他属性(attr2)中的选中属性值(21) 组合成有效(有库存)组合, 则设置该属性(11)为block

好了,接下来就是根据上面总结的两条,来进行程序的实现 点击 商品SKU选择DEMO 可查看demo


 

<!DOCTYPE HTML>

 

<html lang="en-US">

 

<head>

 

<meta charset="UTF-8">

 

<title>商品SKU选择DEMO</title>

 

</head>

 

<body>

 

<style type="text/css">

 

ul,li{ padding:0px; margin:0px;}

 

#panel{ width:500px; margin:30px auto;}

  
  
 

.goods_attr{ overflow:hidden;}

 

.goods_attr .label {font: 12px/30px '宋体';color: #777;width: 50px;;padding-right: 10px;float: left; display:block;}

 

.goods_attr ul {float:left;width:300px;}

  
 

.goods_attr li{color:#333;overflow:hidden;position:relative;float:left;text-align:center; vertical-align:middle; border:1px solid #999;text-indent:0; cursor:pointer}

 

.goods_attr li.b{border:1px dotted #CCC;color:#DDD; pointer:none;}

 

.goods_attr li.b img {opacity:0.4;}

 

.goods_attr li.sel{ border:1px solid #c80a28;color:#333;}

  
 

.goods_attr li.text{margin:5px 10px 5px 0; height:23px;line-height:23px;text-indent:0;padding:0 23px;font-style:normal;}

 

.goods_attr li.img{ margin-right:10px;width:35px;height:35px; line-height:35px;text-align:center;}

  
  
 

</style>

  
 

<div id="panel">

 

<div id="panel_sku_list"><pre></pre></div>

 

<div id="panel_sel">

  
 

</div>

  
 

</div>

  
 

<script src="http://libs.baidu.com/jquery/1.9.0/jquery.min.js"></script>

 

<script type="text/javascript">

 

/*

 

属性集

 

下面一共有4个属性

 

属性item1 下面有 2个属性值 分别是 10,11

 

(举个常见的例子 属性尺码 下有 S M L XL 4个属性值 )

 

*/

 

var keys = {

 

'attr1':['10','11'],

 

'attr2':['20','21','22','23'],

 

'attr3':['30','31','32'],

 

'attr4':['40','41']

 

};

 

//SKU,Stock Keeping Uint(库存量单位)

 

var sku_list=[

 

{'attrs':'10|20|30|40','num':120},

 

{'attrs':'10|21|30|40','num':10},

 

{'attrs':'10|22|30|40','num':28},

 

{'attrs':'10|22|31|41','num':220},

 

{'attrs':'10|22|32|40','num':130},

 

{'attrs':'11|23|32|41','num':120},

 

];

  
  
 

/**init start */

  
 

//显示html结构

 

function show_attr_item(){

 

var html='';

 

for(k in keys){

 

html+='<div class="goods_attr" > <span class="label">'+k+'</span>';

 

html+='<ul>'

 

for(k2 in keys[k]){

 

_attr_id=keys[k][k2];

 

html+='<li class="text" val="'+_attr_id+'" >';

 

html+='<span>'+_attr_id+'</span>';

 

html+='<s></s>';

 

html+='</li>'

 

}

 

html+='</ul>';

 

html+='</div>';

 

}

 

$('#panel_sel').html(html);

 

}

 

//显示数据

 

function show_data(sku_list){

 

var str="";

 

for( k in sku_list){

 

str+=sku_list[k]['attrs']+"\t"+sku_list[k]['num']+"\n";

 

}

 

$('#panel_sku_list pre').html(str);

 

}

  
 

show_data(sku_list);

 

show_attr_item()

  
 

/**init end */

  
 

//获取所有包含指定节点的路线

 

function filterProduct(ids){

 

var result=[];

 

$(sku_list).each(function(k,v){

 

_attr='|'+v['attrs']+'|';

 

_all_ids_in=true;

 

for( k in ids){

 

if(_attr.indexOf('|'+ids[k]+'|')==-1){

 

_all_ids_in=false;

 

break;

 

}

 

}

 

if(_all_ids_in){

 

result.push(v);

 

}

  
 

});

 

return result;

 

}

  
 

//获取 经过已选节点 所有线路上的全部节点

 

// 根据已经选择得属性值,得到余下还能选择的属性值

 

function filterAttrs(ids){

 

var products=filterProduct(ids);

 

//console.log(products);

 

var result=[];

 

$(products).each(function(k,v){

 

result=result.concat(v['attrs'].split('|'));

  
 

});

 

return result;

 

}

  
  
 

//已选择的节点数组

 

function _getSelAttrId(){

  
 

var list=[];

 

$('.goods_attr li.sel').each(function(){

 

list.push($(this).attr('val'));

 

});

 

return list;

 

}

  
 

$('.goods_attr li').click(function(){

 

if($(this).hasClass('b')){

 

return ;//被锁定了

 

}

 

if($(this).hasClass('sel')){

 

$(this).removeClass('sel');

 

}else{

 

$(this).siblings().removeClass('sel');

 

$(this).addClass('sel');

  
 

}

 

var select_ids=_getSelAttrId();

  
 

//已经选择了的规格

 

var $_sel_goods_attr=$('li.sel').parents('.goods_attr');

  
 

// step 1

 

var all_ids=filterAttrs(select_ids);

  
 

//获取未选择的

 

var $other_notsel_attr=$('.goods_attr').not($_sel_goods_attr);

  
 

//设置为选择属性中的不可选节点

 

$other_notsel_attr.each(function(){

 

set_block($(this),all_ids);

  
 

});

  
 

//step 2

 

//设置已选节点的同级节点是否可选

 

$_sel_goods_attr.each(function(){

 

update_2($(this));

 

});

  
  
 

});

  
 

function update_2($goods_attr){

 

// 若该属性值 $li 是未选中状态的话,设置同级的其他属性是否可选

 

var select_ids=_getSelAttrId();

 

var $li=$goods_attr.find('li.sel');

  
 

var select_ids2=del_array_val(select_ids,$li.attr('val'));

  
 

var all_ids=filterAttrs(select_ids2);

  
 

set_block($goods_attr,all_ids);

 

}

  
 

function set_block($goods_attr,all_ids){

  
 

//根据 $goods_attr下的所有节点是否在可选节点中(all_ids) 来设置可选状态

 

$goods_attr.find('li').each(function(k2,li2){

  
 

if($.inArray($(li2).attr('val'),all_ids)==-1){

 

$(li2).addClass('b');

 

}else{

 

$(li2).removeClass('b');

 

}

  
 

});

  
 

}

 

function del_array_val(arr,val){

 

//去除 数组 arr中的 val ,返回一个新数组

 

var a=[];

 

for(k in arr){

 

if(arr[k]!=val){

 

a.push(arr[k]);

 

}

 

}

 

return a;

 

}

  
 

</script>

  
  
  
 

</body>

 

</html>

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值