商品SKU选择实现效果
2018-02-02 16:02
429 查看
商品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换成
20或
22; 因为
10|21
10|22也是一种可行组合(有库存),
10|23不可行,所以需要
20、
22也可选,
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 filte d341 rAttrs(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> |
相关文章推荐
- jquery实现商品拖动选择效果
- jquery实现商品拖动选择效果代码(自写)
- 商品SKU选择实现
- 商品SKU选择实现
- 商品SKU选择实现
- 商品sku规格选择效果,没有商品的不能选中,选择顺序不影响展示结果
- 商品SKU选择实现
- jquery实现商品拖动选择效果代码(自写)
- 关于商城网站商品sku选择的js简易实现
- Material Design系列之Behavior实现支付密码弹窗和商品属性选择效果
- jQuery实现的选择商品飞入文本框动画效果完整实例
- js实现当复选框选择匿名登录时隐藏登录框效果
- Jquery实现类似选择邮箱发送人效果
- [置顶] 仿天猫App实现商品列表布局切换效果
- 贝塞尔曲线实现的购物车添加商品动画效果
- 实现TreeGrid中复选框的级联选择效果(类似zTree的选择效果)
- 仿商业网站——商品评分效果的实现
- Android 商品属性SKU选择