jQuery绑定复选框父div点击事件时is(':checked')单次点击返回双值问题
问题原因分析
- 核心触发点是
<label>标签的默认交互特性:点击包含<input>的<label>区域时,浏览器会先后触发两次点击事件,第一次是label本身的点击事件,第二次是浏览器主动触发的对应input的点击事件,两次事件都会向上冒泡到父级#my-id容器,导致绑定在div上的click回调执行两次。 - 第一次执行回调时input的选中状态还未被修改,输出原始状态;第二次执行时input状态已经被label的默认行为修改,输出变更后的状态,因此会出现两次相反的日志输出,连带触发两次slide动画导致页面抖动。
解决建议
提供两种可直接落地的修复方案:
方案1:绑定input的change事件(最推荐)
change事件仅会在input选中状态发生实际变更时触发一次,完全不受事件冒泡影响,逻辑更稳定:
$("#my-id").find('input').unbind('change').change(function(){ if($(this).is(':checked')){ console.log('checked'); // 替换为你的slideDown逻辑 } else { console.log('not checked'); // 替换为你的slideUp逻辑 } });
点击div内任意区域触发label切换input状态时,都会触发一次change事件,不会出现重复触发问题。
方案2:保留div点击绑定,阻止默认行为
如果需要保留绑定在div上的点击事件逻辑,可在回调中阻止label的默认行为,手动控制input状态切换,避免浏览器自动触发额外点击事件:
$("#my-id").unbind('click').click(function(e){ const $targetInput = $(this).find('input'); // 阻止label默认触发input点击的行为,避免二次事件 e.preventDefault(); // 手动切换选中状态 $targetInput.prop('checked', !$targetInput.is(':checked')); if($targetInput.is(':checked')){ console.log('checked'); // 替换为你的slideDown逻辑 } else { console.log('not checked'); // 替换为你的slideUp逻辑 } });
内容的提问来源于stack exchange,提问作者Patrick Wendel
相关产品推荐
相关产品推荐

