实现一个类似淘宝详情页面商品参数模态框页面
希望实现的目标是:
1、款式radio组 和 颜色分类radio组 各radio之间呈现互斥状态,即选中的radio由背景,其他的没有背景
2、各radio组内部能实现 首次点击选中并带有,再次点击取消选中及背景
本例使用了bootstrap样式及jquery,需要先包含必需的框架
html代码部分:
本例使用的是laravel框架的blade模板,$uniquesizes as $sizes 都是控制器传过来的参数,自行测试的可以去除,相关参数直接用自定义的数据代替
<div>款式</div>
<div class="clearfix">
@foreach($uniquesizes as $sizes)
<div name="divsizes" class="float-left bg-light m-1 px-2 py-1 text-center rounded-lg" style="position: relative; height: 30px;">
<input type="radio" name="sizes" value="{{$sizes}}" style="position: absolute;left: 0; top: 0; width: 100%; height: 100%;opacity: 0.5;" >{{$sizes}}
</div>
@endforeach
</div>
<div>颜色分类</div>
<div class="clearfix">
@foreach($good->size as $colors)
<div name="divcolors" class="float-left bg-light m-1 px-2 py-1 text-center rounded-lg" style="position: relative; height: 30px;">
<input type="radio" name="colors" value="{{$colors['colors']}}" style="position: absolute;left: 0; top: 0; width: 100%; height: 100%;opacity: 0.5;">
<img src="/upload/{{isset($colors['sizeimg'])?$colors['sizeimg']:''}}" alt="" width="30" height="30"> {{$colors['colors']}}
</div>
@endforeach
</div>
juqery代码部分:
var colorobj = $('[name="divcolors"]'); // 获取所有颜色div元素的对象
var sizeobj = $('[name="divsizes"]'); // 获取所有款式div元素的对象
// 设置款式单选按钮点击样式
$('input:radio[name="sizes"]').click(function () {
// 设置radio外层div的动态样式
setRadioDivActive(sizeobj,$(this).val());
// 实现单次点击选中 再次点击取消的状态
setRadioCheckActive($(this));
}).change(function () {
// 设置radio切换时的样式
setRadiosChangeActive(sizeobj,$(this));
});
// 设置颜色分类单选按钮点击样式
$('input:radio[name="colors"]').click(function () {
setRadioDivActive(colorobj,$(this).val());
setRadioCheckActive($(this));
}).change(function () {
setRadiosChangeActive(colorobj,$(this));
});
// 设置radio外层div sizes和colors的点击时动态效果
// 设置选中radio的div背景及文字颜色 以及恢复其他所有未选中的radio的背景及文字颜色
function setRadioDivActive(obj,value){
for (var j=0;j<obj.length;j++){
var getinput = obj.find('input')[j];
if ($(getinput).val() == value){
$(obj[j]).addClass("bg-warning").removeClass("bg-light");
}else{
$(obj[j]).addClass("bg-light").removeClass("bg-warning");
}
}
}
// 设置radio 一次点击选中,再次点击取消选中
function setRadioCheckActive(thisobj) {
if (thisobj.data('waschecked') == true){
thisobj.prop('checked', false);
thisobj.data('waschecked', false);
console.log(thisobj.parent().addClass("bg-light").removeClass("bg-warning"));
} else {
thisobj.prop('checked', true);
thisobj.data('waschecked', true);
}
}
// 设置radio切换选择时的状态
// 添加这个方法,主要是因为在按钮组下,使用setRadioCheckActive()方法时会存在问题
// 即当选中一个radio后,再点击另外一个radio,此时radio选中状态都正常,但是再重复上面操作时,会出现两个radio都未选中的情况
// 个人分析应该是thisobj.data(); 这个存储waschecked状态的问题,在切换radio时,应该要清除按钮组下所有radio的waschecked值
function setRadiosChangeActive(obj,thisobj) {
// 遍历当前radio组下的所有radio对象
for (var j=0;j<obj.length;j++){
// 这里obj是radio外层的div对象,所以需要通过find获取其下面的input值
var getinput = obj.find('input')[j];
// thisobj是当前点击的radio按钮对象
// 对比当前radio对象值与当前循环遍历的radio值,如果一致,则设置为选中状态
if($(getinput).val()==thisobj.val()){
$(getinput).prop("checked",true);
}else { // 否则,radio按钮组里的其他所有radio的状态设置为未选择,并设置('waschecked', false)
// $(getinput).prop("checked", false);
$(getinput).data('waschecked', false);
}
}
}
注意:
// 取消之前所有的colors元素的选中状态 会删除radio被选中样式
$('input:radio[name="colors"]').prop("checked",false);
// 取消之前所有的colors元素的选中状态 会保留radio被选中样式
$('input:radio[name="colors"]').attr("checked",false);