点击confirm弹窗取消按钮时如何阻止checkbox被选中?
问题根源
代码不生效是两个写法错误加一个事件执行顺序问题导致的:
- 事件执行顺序问题:点击checkbox时,
ActivateReg函数会先执行,等函数执行完浏览器才会触发checkbox默认的选中状态切换。你在else分支里设置checked=false的时候,浏览器还没把checkbox改成选中状态,等函数跑完,默认行为直接把状态切为选中,把你之前的设置覆盖了。 - 选择器匹配不到元素:你写的HTML里checkbox的id固定是
chkbox,JS里拼出来的选择器是#chkbox + bID,根本找不到对应元素;另外你内联onclick的传参写法错误,三个参数被包裹在同一组引号里,实际只会传进去一个拼接后的字符串,cID和crID两个参数永远是undefined,就算你想拼三个参数的id也拼不对。 - 逻辑时序问题:就算你选择器写对了,因为前面说的执行顺序问题,你提前设置的false也会被后续默认行为覆盖。
修复方法
最简便的写法:直接把当前checkbox对象传入函数
不用费劲拼接id选择器,也不用纠结时序问题,直接在点击时把当前元素传进函数,等confirm返回结果后直接操作当前元素即可。
HTML代码修正:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <!-- 注意参数之间的引号分隔,第一个参数传this代表当前checkbox元素 --> <input type="checkbox" id="chkbox" onclick="ActivateReg(this, '参数1', '参数2', '参数3')" class="listCheckbox" />
JS代码修正:
function ActivateReg(currentCheckbox, bID, cID, crID) { console.log(bID, cID, crID); const userConfirmed = confirm("Do you really sure?"); if (userConfirmed) { // 这里写你的ajax请求逻辑 // $.ajax({ // 你的接口配置 // }) } else { // 直接操作当前传入的checkbox元素,设置为未选中 currentCheckbox.checked = false; // jQuery写法:$(currentCheckbox).prop("checked", false); } }
更推荐的写法:用事件委托+阻止默认行为
如果是动态渲染的列表类checkbox,不要写内联onclick,用jQuery事件委托更易维护,直接在用户点取消时阻止默认选中行为,从根源避免状态覆盖问题:
// 页面加载完成后绑定事件 $(function() { $(document).on('click', '.listCheckbox', function(e) { const userConfirmed = confirm("Do you really sure?"); if (!userConfirmed) { // 点取消直接阻止checkbox默认选中行为 e.preventDefault(); return false; } // 用户点确认的逻辑写在这里,参数可以存在元素的data属性上读取 // const bID = $(this).data('bid'); // const cID = $(this).data('cid'); // const crID = $(this).data('crid'); // 后续ajax请求 }) })
对应的HTML不需要写内联事件,把参数存在data属性上即可:
<input type="checkbox" class="listCheckbox" data-bid="对应bID值" data-cid="对应cID值" data-crid="对应crID值" />
如果你一定要用id拼接的方式找元素,必须保证两点:一是渲染HTML时,input的id和你JS里拼接的id字符串完全一致;二是不要在onclick函数执行过程中改checked,要么用
e.preventDefault()提前阻止默认行为,要么加个setTimeout把设置checked的逻辑放到事件队列末尾等默认行为执行完再改,不过这种写法远不如上面两种方案稳妥。
内容的提问来源于stack exchange,提问作者tSv
相关产品推荐
相关产品推荐

