jQuery动态生成checkbox控制radio禁用失效,循环不执行如何解决?
问题根因
- 异步执行顺序错误
$.ajax是异步请求,你将ajdTrx()写在ajax请求外部,会在接口返回、success回调执行、DOM生成之前就触发ajdTrx,此时temp是空数组,自然不会进入循环,也找不到刚生成的checkbox、radio元素。
- 异步执行顺序错误
- 数组结构不符合预期
你在success回调中执行temp.push(result),把整个接口返回对象塞进temp数组,temp.length永远等于接口请求次数,而你的checkbox、radio的索引是遍历result.data(接口返回的列表数据)生成的,循环长度不匹配,就算执行了循环也无法正确绑定所有元素。
- 数组结构不符合预期
- 动态元素绑定方式不稳定
直接给动态生成的元素绑定onchange事件,每次重新渲染DOM后都需要重新绑定,容易出现遗漏。
- 动态元素绑定方式不稳定
最优解决方案(事件委托,无需循环绑定)
改用事件委托方案,只需在页面初始化时绑定一次,无需关心元素生成时机,也不需要每次ajax请求后重新绑定,稳定性更高:
- 直接删除原
ajdTrx函数,以及prepAcc函数末尾的ajdTrx()调用 - 页面初始化时添加如下绑定逻辑:
$(function() { // 给表格父元素绑定事件,代理所有id以rp开头的checkbox的change事件 $('#tableAcc').on('change', 'input[type="checkbox"][id^="rp"]', function() { // 提取当前checkbox的索引 const index = this.id.replace('rp', ''); // 找到对应索引的radio const $targetRadio = $('#trx' + index); // 修改radio禁用状态,用prop修改状态比attr更准确 $targetRadio.prop('disabled', !this.checked); // 可选:取消勾选checkbox时自动取消radio的选中状态,逻辑更合理 if (!this.checked) { $targetRadio.prop('checked', false); } }); });
兼容原写法的修改方案
如果你不想改动原有逻辑结构,按以下步骤修改即可:
- 调整
ajdTrx调用位置:将prepAcc函数末尾的ajdTrx()移动到success回调的最后一行,也就是$("#allAccString").val(s);之后,保证DOM生成、数据赋值完成后再执行绑定。 - 修正
temp数组逻辑:prepAcc函数开头添加temp = [];清空旧数据,避免多次请求后数组长度异常。 - 修正循环长度:将
ajdTrx的循环条件改为for (let index = 0; index < temp[0].data.length; index++),匹配列表实际长度。 - 状态修改优化:将
sendbtn.disabled = false/true改为$(sendbtn).prop('disabled', !this.checked),避免属性修改不生效的问题。
内容的提问来源于stack exchange,提问作者Ilham Abdurrahman
相关产品推荐
相关产品推荐

