通常情况下 用label 标签 包含 属性值为checkbox的 input标签,即可实现点击文案改变checkbox 样式效果,如下:
<label><input type="checkbox" />复选项一</label>
但,实际运用当中,我们需要实现的效果,可能是这个样子的,如下图
如果把 后面这些都放到label标签内,不是很现实。
实例:
需要实现的效果有:
1)点击复选框项与 后面元素,check 的 true 和 false 效果切换
2)点击 全选 按钮, 复选框项 切换
3)已选择 数量 实现;
<div class="accountMain">
<div class="accountSelect">
<div class="account-item">
<label class="checkBox-item" name="account"><input type="checkbox" /></label>
<div class="layRow flexTop">
<div class="account">
<img class="head" src="../../asset/images/avatar.png"><!--头像-->
<span class="platform"><img src="../../asset/images/platform/bilibili.png"></span><!--平台-->
</div>
<div class="ml-8">
<p class="accountName">用户名</p>
<p class="accountPlatform">bilibili</p>
</div>
</div>
</div>
<div class="account-item">
<label class="checkBox-item" name="account"><input type="checkbox" /></label>
<div class="layRow flexTop">
<div class="account">
<img class="head" src="../../asset/images/avatar.png"><!--头像-->
<span class="platform"><img src="../../asset/images/platform/bilibili.png"></span><!--平台-->
</div>
<div class="ml-8">
<p class="accountName">用户名</p>
<p class="accountPlatform">bilibili</p>
</div>
</div>
</div>
</div>
<div class="accountAllSelect">
<label class="checkBox-item"><input type="checkbox" aloneState="false" />全选</label>
</div>
</div>
<div class="chooseNum">已选择:<span class="ml-8">0</span></div>
.checkBox-item {
min-height: 32px;
display: flex;
align-items: center;
line-height: 18px;
color: #666;
cursor: pointer;
}
.checkBox-item input {
width: 16px;
height: 16px;
display: inline-block;
margin-right: 8px;
background-color: #fff;
border: 1px solid #D9D9D9;
border-radius: 4px;
transition: background ease 1ms;
-webkit-appearance: none;
-webkit-user-select: none;
user-select: none;
position: relative;
cursor: pointer;
}
.checkBox-item input:hover,
.checkBox-item input:active {
border-color: #1E62EC;
}
.checkBox-item input:checked {
border-color: #1E62EC;
background-color: #1E62EC;
color: #fff;
}
.checkBox-item input:checked:after {
content: '';
top: 4px;
left: 3px;
position: absolute;
background: transparent;
border: #fff solid 1px;
border-top: none;
border-right: none;
height: 3px;
width: 7px;
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
transform: rotate(-45deg);
}
.checkBox-item input:disabled,
.checkBox-item input:checked:disabled {
border-color: #D9D9D9;
background-color: #D9D9D9;
}
/*复选框 全选 局部选中样式 */
.checkBox-item input[aloneState="true"] {
border-color: #1E62EC;
background-color: #fff;
}
.checkBox-item input[aloneState="true"]:before {
content: '';
height: 8px;
width: 8px;
top: 3px;
left: 3px;
position: absolute;
background: #1E62EC;
border-radius: 1px;
}
/*选择账号 单 复选框*/
$('.publishPage').on('click', '.account-item', function () {
this.getElementsByTagName('input')[0].toggleAttribute('checked');
let b = $(this).find('input').attr('checked');
b == 'checked' ? $(this).find('input').prop('checked', true) : $(this).find('input').prop('checked', false);
let num = $(this).siblings().length + 1;
let a = 0;
$(this).parent().children().each(function () {
if ($(this).find('input').prop('checked')) a++;
})
if (a == 0) {
$('.accountAllSelect').find('input').attr('aloneState', false).prop('checked', false);
} else if (a == num) {
$('.accountAllSelect').find('input').attr('aloneState', false).prop('checked', true);
} else {
$('.accountAllSelect').find('input').attr('aloneState', true).prop('checked', false);
}
$(this).parents('.accountDialog').find('.dialogBottomBtn').children('.chooseNum').children('span').text(a);
})
/*选择账号 全选 复选框*/
$('.publishPage').on('click', '.accountAllSelect .checkBox-item', function () {
$(this).find('input[aloneState]').attr('aloneState', false);
let state = $(this).find('input').prop('checked');
$('.accountSelect').find('[name="account"]').children('input').prop('checked', state).attr('checked', state);
let a = $(this).parents('.accountDialog').find('.dialogBottomBtn').children('.chooseNum').children('span');
let num = $('.accountSelect').children().length;
state ? a.text(num) : a.text(0);
})
重点代码解析:
在写单个子项点击效果时,不想使用if 判断 最好 有类似于 jQuery toggleClass() 方法,一句话搞定,但是 jQuery 没有类似方法,但原生 js 有toggleAttribute(),满足 DOM下 checked的切换。
写法如下:
this.getElementsByTagName('input')[0].toggleAttribute('checked');
该方法正常子项点击效果切换没问题,但点击全选按钮后,再点击子项后面的div 不能切换checked 样式。
- property 是DOM节点的属性,是JavaScript里的对象;
- attribute 是HTML标签上的特性,表现为DOM节点的attributes属性;
所以,还得添加判断,是为了更改prop(‘checked’)属性值
let b = $(this).find('input').attr('checked');
b == 'checked' ? $(this).find('input').prop('checked', true) : $(this).find('input').prop('checked', false);
本以为 到此结束,后经过测试,发现 全选/全不选 按钮通过如下方法实现效果时,
全选后再点击子选项的第一次 ,样式不发生改变,之后的 第三次 第四次.. 点击 ,正常显示
全选/全不选 代码如下:
let state = $(this).find('input').prop('checked'); //获取全选 值
$('.accountSelect').find('[name="account"]').children('input').prop('checked', state);
//赋值给子选项
原来是,通过prop()取值赋值,html 上 属性不发生改变
所以,全选 事件 优化为:
let state = $(this).find('input').prop('checked');
$('.accountSelect').find('[name="account"]').children('input').prop('checked', state).attr('checked', state);
讲解的不够详细明白,但是大概领会精神吧,海涵~~