点击事件监听器仅首次生效问题:需每次触发checkSlotsChoosen函数
问题原因及修复方案
核心原因
- 动态元素未被监听:初始通过
querySelectorAll获取的.availableslot a仅包含页面加载时的元素,若页面后续动态生成新的时段按钮,这些新元素没有绑定点击事件,导致点击不触发checkSlotsChoosen。 - 重复绑定事件引发逻辑异常:每次调用
checkSlotsChoosen都会给所有.cancel按钮添加点击事件,重复绑定会导致同一按钮触发多次函数执行,干扰正常逻辑,甚至可能引发页面性能问题。 - 禁用状态拦截点击事件:若
.disable类的CSS设置了pointer-events: none,当按钮处于禁用状态时,点击事件会被直接拦截,无法触发函数。
修复步骤
1. 改用事件委托监听动态元素
放弃直接给单个元素绑定事件,改为将事件委托到文档根节点,这样无论元素是初始加载还是动态生成,都能触发事件:
// 替换原有的slotsAvailables循环绑定代码 document.addEventListener('click', function(e) { // 判断点击目标是否是availableslot按钮 if (e.target.closest('.availableslot a')) { checkSlotsChoosen(); } // 同时处理cancel按钮的点击 if (e.target.closest('.cancel')) { checkSlotsChoosen(); } });
2. 移除函数内的重复事件绑定
删除checkSlotsChoosen函数中绑定.cancel事件的for循环代码,避免重复绑定。
3. 调整禁用状态的交互逻辑(可选)
如果希望按钮在禁用状态下点击仍能执行checkSlotsChoosen,修改.disable类的CSS,移除pointer-events: none属性,改用视觉样式提示禁用状态:
.disable { opacity: 0.6; cursor: not-allowed; /* 移除 pointer-events: none; */ }
修复后的完整代码
var buttonBooking = document.querySelector('.pbSubmit'); buttonBooking.classList.add('disable'); function checkSlotsChoosen(){ var slotsChoosen = document.querySelectorAll('.availableslot.currentSelection'); if(slotsChoosen.length === 0){ buttonBooking.classList.add('disable'); console.log('disable btn'); }else{ buttonBooking.classList.remove('disable'); console.log('active btn'); } } // 事件委托处理时段按钮和取消按钮的点击 document.addEventListener('click', function(e) { if (e.target.closest('.availableslot a')) { checkSlotsChoosen(); } if (e.target.closest('.cancel')) { checkSlotsChoosen(); } }); // 绑定预订按钮的点击事件 buttonBooking.addEventListener('click', checkSlotsChoosen);
内容的提问来源于stack exchange,提问作者Jo V
相关产品推荐
相关产品推荐

