问题描述
最近在做项目是遇到自定义checkbox多选需求,点击label时,触发了两次点击事件
页面元素
<div class="multi-list hasTip bb pb-10">
<div class="tit c6">机构属性:</div>
<div class="mulit-item" id="institution">
<label class="checkBtn checkBtn-default mr-10">
<input class="checkbox" type="checkbox" value="银行个贷">银行个贷
</label>
<label class="checkBtn checkBtn-default mr-10">
<input class="checkbox" type="checkbox" value="消费金融">消费金融
</label>
<label class="checkBtn checkBtn-default mr-10">
<input class="checkbox" type="checkbox" value="典当行">典当行
</label>
<label class="checkBtn checkBtn-default mr-10">
<input class="checkbox" type="checkbox" value="信贷中介">信贷中介
</label>
</div>
</div>
点击事件
$(".multi-list").on("click","label.checkBtn",function(){
if($(this).hasClass("selected")){
console.log("删除");
$(this).removeClass("selected");
}else{
console.log("选中");
$(this).addClass("selected");
}
})
看下图,神奇的事情发生了!!!竟然label没有选中的样式,还 把 “选中” 和 “删除” 都给我打印出来了,同时满足这两个矛盾的条件是不可能的,那到底是什么原因呢?
原因:原来是label和input标签嵌套,点击label的时候,事件冒泡一次,同时会触发关联的input的click事件,导致事件再次冒泡,以至于自定义的复选框达不到我们想要的效果
点击label的时候打印“选中”,label添加class selected,当事件冒泡到input时,已经满足条件$(this).hasClass("selected"),打印“删除”,删除class selected,由于这个时间很短,这就是为什么我点击label没有给它添加样式了
那我们怎么解决呢?
方法一、对event.target进行判断
$(".multi-list").on("click","label.checkBtn",function(event){
if($(event.target).is('input')){//对点击目标元素做判断
return;
}
if($(this).hasClass("selected")){
console.log("删除");
$(this).removeClass("selected");
}else{
console.log("选中");
$(this).addClass("selected");
}
})
方法二、将事件绑定在input checkbox上,我们就不会触发label的click事件了
$(".multi-list").on("click","input.checkbox",function(){
if(!$(this).parent().hasClass('selected')){
console.log("选中");
$(this).parent().addClass("selected");
}else{
console.log("删除");
$(this).parent().removeClass("selected");
}
})
我们可以看到下图已经有选中的样式了