浏览 AI使用教程

表单怎样补齐校验、错误、禁用和提交中状态

一个能输入、能提交的表单,还不等于能用。空值、格式错误、接口失败、重复提交和提交中状态,都需要明确反馈和恢复路径。

按实际操作顺序推进

每完成一段就检查当前输出,确认结果符合预期后再继续。

  1. 01准备动手前,把材料和不能改的部分定下来
  2. 02执行完整字段关联与异步恢复示例
  3. 03检查为什么“错误提示完整,键盘用户仍无法完成”还不能交付
  4. 04完成表单状态矩阵与交互验收通过哪些检查才算完成
从手头这一份材料开始

表单最容易漏掉的,往往不是输入框,而是出错以后怎么办

注册表单只有输入框和提交按钮。弱密码提交后页面无反应;重复点击产生两次请求;接口返回邮箱已存在时错误显示在顶部,用户不知道改哪一项。

  • 字段与全局错误正确归位
  • 重复提交被阻止
  • 键盘、焦点和成功跳转已验证
本例材料

动手前,把材料和不能改的部分定下来

需要确认本例内容
现有材料下方完整HTML仅模拟注册响应,邮箱、密码、协议三字段;无真实接口、邮件或账户创建。不要输入真实密码。
不能越过的边界客户端提示用于体验,服务端仍执行最终校验;提交中防重复;错误与字段或全局状态正确对应。
要交付的结果表单状态矩阵与交互验收
实际操作

表单交互状态设计,从“字段与校验”开始做

字段与校验

区分必填、格式、范围、跨字段和服务端规则,错误文案说明怎么修,不只写无效。

触发时机

决定输入中、失焦或提交时校验,避免过早打断,也避免提交后只在页面顶部报错。

提交中与幂等

提交后防重复操作,展示进度;后端使用幂等或唯一约束处理重复请求。

成功与失败

成功说明发生了什么和下一步;失败保留用户输入,区分可重试、需修改和无权限。

键盘与可访问性

标签、描述、错误关联、焦点顺序和按钮状态对键盘与辅助技术可理解。

完整字段关联与异步恢复示例

signup.html

浏览器打开后选择模拟响应

<!doctype html>
<html lang="zh-CN"><meta charset="utf-8"><title>注册状态练习</title>
<form id="signup" novalidate>
<label for="email">邮箱</label><input id="email" type="email" aria-describedby="email-error">
<p id="email-error"></p>
<label for="password">密码(教学值即可)</label><input id="password" type="password" aria-describedby="password-error">
<p id="password-error"></p>
<label><input id="terms" type="checkbox" aria-describedby="terms-error">同意协议</label><p id="terms-error"></p>
<label for="scenario">模拟响应</label><select id="scenario"><option>201</option><option>409</option><option>422</option><option>429</option><option>500</option></select>
<button id="submit">注册</button><p id="message" role="status" aria-live="polite"></p>
</form>
<script>
const el=id=>document.getElementById(id);
let busy=false;
el('signup').addEventListener('submit',async event=>{
 event.preventDefault(); if(busy)return;
 for(const id of ['email','password','terms']){el(id).removeAttribute('aria-invalid');el(id+'-error').textContent='';}
 el('message').textContent='';
 const errors=[];
 if(!el('email').value || !el('email').validity.valid)errors.push(['email','请输入完整邮箱']);
 if(el('password').value.length<8)errors.push(['password','请输入至少8位教学密码']);
 if(!el('terms').checked)errors.push(['terms','请确认协议']);
 function showError(id,text){el(id).setAttribute('aria-invalid','true');el(id+'-error').textContent=text;}
 if(errors.length){for(const [id,text] of errors)showError(id,text);el(errors[0][0]).focus();return;}
 busy=true;el('submit').disabled=true;el('submit').textContent='提交中';
 try{
  await new Promise(resolve=>setTimeout(resolve,800));
  const status=Number(el('scenario').value);
  if(status===201){el('message').textContent='教学成功:下一步验证邮箱。本例没有真实注册或发邮件。';}
  else if(status===409){showError('email','本教学响应表示邮箱已存在,请核对或登录');el('email').focus();}
  else if(status===422){showError('password','教学服务端拒绝该密码,请更换');el('password').focus();}
  else if(status===429){el('message').textContent='教学限流:稍后重试,不要连续提交';}
  else{throw new Error('request-demo-17');}
 }catch(error){el('message').textContent='提交失败,输入已保留。教学请求ID:'+error.message;}
 finally{busy=false;el('submit').disabled=false;el('submit').textContent='注册';}
});
</script></html>

role=status用于结果通知,aria-describedby把说明关联到字段,aria-invalid标错误。只阻止当前页面重复点击;真正接口仍需校验、授权、唯一约束与必要的幂等。

全部用同一注册表单复测

操作预期证据
空邮箱提交无模拟请求,焦点在邮箱字段错误与焦点
合法输入选409邮箱错误,保留其它输入aria-invalid及按钮恢复
选429后再提交全局提示,按钮恢复不变成永久禁用
选500显示request-demo-17并保留输入异常finally恢复
选201只显示教学成功,不冒充真实发邮件提示文本
最终输出

完成后的表单状态矩阵与交互验收

预期本地校验失败聚焦首个字段;409关联邮箱,422关联密码,429给全局提示,500保留输入并恢复按钮;201显示验证邮箱下一步。未实际连注册服务,前端防重复不代替服务端幂等。

常见失败

为什么“错误提示完整,键盘用户仍无法完成”还不能交付

错误提示完整,键盘用户仍无法完成

原因
焦点、标签与错误关联未实现
怎么改
使用真实键盘流程和辅助技术检查焦点顺序、aria 描述与提交后定位
验收方式

表单状态矩阵与交互验收通过哪些检查才算完成

进一步核对

前端与网页:参考资料与核对入口