如何为已绑定点击事件的按钮新增前置校验,不改动原有通用绑定代码
解决方案
你现有的代码无法拦截原有提交逻辑,是因为jQuery的同类型事件按绑定顺序执行,原有提交事件先绑定,会在校验逻辑之前执行,自然拦不住。
方案1:调整事件队列顺序(兼容性最佳)
这个方案不需要改动原有通用逻辑,仅在当前特定页面插入代码即可生效,支持二次确认后手动触发原有提交逻辑:
// 仅在当前特定页面执行这段代码 const $targetBtn = $('button'); // 取出按钮上已绑定的所有原有点击事件 const originClickHandlers = $._data($targetBtn[0], 'events').click.map(item => item.handler); // 清空原有点击事件绑定 $targetBtn.off('click'); // 先绑定我们的前置校验逻辑 $targetBtn.click(function (e) { if($(this).data('value') != 'ready') { $('ul').append('<li>condition not met, data not submitted</li>'); // 阻止后续所有绑定的点击事件执行 e.stopImmediatePropagation(); // 此处可插入你的二次确认弹窗逻辑 // 若用户确认提交,可手动调用原有提交逻辑:originClickHandlers[0].call(this, e) return; } }); // 把原有提交事件重新绑定到队列末尾 originClickHandlers.forEach(handler => $targetBtn.click(handler));
方案2:捕获阶段拦截(代码更简洁)
利用浏览器事件流的捕获阶段优先于冒泡阶段执行的特性,直接绑定捕获阶段的校验事件,不需要修改原有事件队列:
// 仅在当前特定页面执行这段代码 document.querySelector('button').addEventListener('click', function(e) { if(this.dataset.value !== 'ready') { $('ul').append('<li>condition not met, data not submitted</li>'); // 阻止后续所有事件执行,包括冒泡阶段的原有提交逻辑 e.stopImmediatePropagation(); // 此处可插入你的二次确认弹窗逻辑 } }, true); // 第三个参数为true代表绑定在捕获阶段
两种方案都可以实现你要的效果:条件不满足时仅打印condition not met, data not submitted,不会触发原有提交逻辑打印submitting data,且不会影响其他页面的原有按钮逻辑。
内容的提问来源于stack exchange,提问作者Don Giulio
相关产品推荐
相关产品推荐

