Laravel如何实现点击注册按钮后禁用、改文本并保持禁用状态?
代码问题定位
- 无效的事件绑定写法:你给
<button>元素绑定了submit事件,但submit事件是<form>元素专属的触发事件,按钮本身不会派发这个事件,你之前写的禁用逻辑根本没有被实际执行。你看到的“按钮短暂禁用后恢复”的现象,是reCAPTCHA SDK在交互完成后自动重置按钮DOM状态导致的,和你自己写的代码无关。 - 脱离实际的固定延时逻辑:用
setTimeout固定5秒后恢复按钮,完全没有匹配真实业务的动态耗时——网络好的时候注册请求可能1秒就返回了,网络差的时候可能10秒都没处理完,固定时间开关按钮根本无法覆盖全场景。 - 没有适配现有reCAPTCHA的流程:你的按钮已经配置了
data-callback='onSubmit',也就是人机验证通过后会触发这个全局回调,你之前的代码完全绕开了这个流程节点,自然会出现状态被SDK重置的问题。
可落地的实现方案
按照表单提交流程的标准逻辑做改造,核心调整点:
- 把事件绑定从按钮转移到表单元素上,不管是点击按钮提交、还是按回车触发提交,都能统一拦截处理
- 在表单校验通过、真正触发提交的节点,给按钮加
disabled属性,同时把按钮文本改成请稍候... - 删除写死的延时恢复逻辑,按钮的解禁时机完全跟着真实的接口状态走:只有接口返回校验错误、网络异常的时候,才把按钮恢复成可点击、原文本的状态;如果提交成功直接跳转页面,不需要额外处理按钮状态
- 适配reCAPTCHA的回调机制,利用已配置的
onSubmit全局回调,在人机验证通过后再手动触发表单提交,避免流程顺序错乱
修正后的完整代码参考:
<!-- 确认按钮在表单内部,给表单加个id方便获取元素 --> <form id="register-form" method="POST" action="/register"> @csrf <button id="disable-submit" type="submit" class="g-recaptcha btn btn-light rounded-pill" data-sitekey="{{ config('services.recaptcha.sitekey') }}" data-callback='onSubmit' data-action='submit'> {{ __('Register') }} </button> </form>
// 对应reCAPTCHA的全局回调,验证通过后触发 function onSubmit() { // 手动触发表单提交 document.getElementById('register-form').requestSubmit(); } (function(){ const registerForm = document.getElementById('register-form'); const submitBtn = document.getElementById('disable-submit'); // 预先保存按钮原始文本,方便后续恢复 const originalBtnText = submitBtn.textContent.trim(); // 监听表单提交事件 registerForm.addEventListener('submit', function(e) { // 先做原生表单校验,校验不通过直接阻断流程 if (!registerForm.checkValidity()) { e.preventDefault(); return false; } // 校验通过,禁用按钮+修改文本 submitBtn.disabled = true; submitBtn.textContent = '请稍候...'; }); // 注册场景下,当接口返回校验错误/网络异常时,恢复按钮状态 // 你可以在AJAX的error回调里手动触发这个自定义事件 window.addEventListener('register:submit-failed', function() { submitBtn.disabled = false; submitBtn.textContent = originalBtnText; }); })();
注意:如果你是用AJAX方式提交注册请求,不需要在success回调里恢复按钮——提交成功后会直接跳转页面,页面刷新后按钮本身就是初始状态。只需要在AJAX的error回调(接口返回422校验错误、网络异常等场景)里解禁按钮、恢复原文本即可。
内容的提问来源于stack exchange,提问作者J C
相关产品推荐
相关产品推荐

