题目重点:name/phone/email规则注入、逐字段错误状态、submit拦截与原子append;原题正则条件保留待核。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 调用方提供form、三个input、对应error元素、tbody和纯同步validate(values)回调。validate返回字段→错误字符串,空字符串/缺失表示通过。
- 原姓名长度/电话格式/邮箱规则缺失,示例不编造正则。训练测试规则只为验证流程,不能当原OA条件。
- 每次合法提交追加一行,保留原输入文本、不自动重置/去重;这些正式政策待核,调用方可配置。
解题路线
- 监听submit而不只click,键盘Enter也走相同验证路径;preventDefault防浏览器导航。取一次输入快照,交给明确规则层,避免边验边append。
- 每次同时刷新三字段error与aria-invalid,旧错误在合法修正后清除;先判全部字段无错误,才构造tr和三个td。任何一个字段失败不修改已有表行。
- 用textContent把文本写入cell/error,姓名含<等字符不成为HTML。原DOM selectors/顺序/测试合同需实际提供;本文参数注入不猜原ID。
- 规则层可以共享后端合同,但客户端校验只改善交互,服务端仍验证真实请求。邮箱/电话复杂格式不由一条回忆帖推全球通用正则。
- 错误应有可关联的说明,可给输入aria-describedby和错误摘要/首错焦点策略;原控件结构未知时不能伪称完成全部a11y。代码只保持字段状态与提交原子性。
- 异步规则若加入要给提交版本/取消与重复点击政策,不能用本文同步回调却返回Promise当空errors通过。disposer移除listener,避免多次挂载重复append。
手动走一遍
自拟姓名通过、电话失败、邮箱通过时表格一行都不增加;修正后提交新增完整3-cell行,并清掉旧电话error。3,600动作状态与预先列好的合法/非法fixture独立核DOM,30次listener清理、3个无效validator返回值及文本安全检查通过;fixture格式不是原题规则。
JavaScript 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
// Exact name/phone/email rules are caller supplied; original OA rules are unknown.
export function mountValidatedForm({ form, fields, errorElements, tbody, validate }) {
const keys = ["name", "phone", "email"];
const submit = event => {
event.preventDefault();
const values = Object.fromEntries(keys.map(key => [key, fields[key].value]));
const errors = validate(values);
if (!errors || typeof errors !== "object" || Array.isArray(errors) || typeof errors.then === "function") throw new Error("validator must return an error mapping");
let invalid = false;
for (const key of keys) {
const message = errors[key] ?? "";
errorElements[key].textContent = message;
fields[key].setAttribute("aria-invalid", String(Boolean(message)));
invalid ||= Boolean(message);
}
if (invalid) return;
const row = tbody.ownerDocument.createElement("tr");
for (const key of keys) {
const cell = tbody.ownerDocument.createElement("td");
cell.textContent = values[key];
row.append(cell);
}
tbody.append(row); // Append only after all checks and cells are ready.
};
form.addEventListener("submit", submit);
return () => form.removeEventListener("submit", submit);
}
复杂度
三个字段同步验证成本取决于规则,DOM追加固定3cell约O(1),R合法提交保留O(R)行。正则/远程校验/输入长度成本须另算,不把整个验证函数泛写O(1)。
易错点与追问
容易失分的边界
- 只监听按钮click。
- 一个字段成功就先append半行。
- 旧error不清。
- 假定某正则就是原题。
- innerHTML写输入。
- Promise误作同步错误映射。
继续深挖
- async重复提交怎样防旧结果覆盖?
- 错误摘要怎样与字段关联?
- 重复合法提交是否应幂等?
- 原规则含Unicode名字怎样测试?
