Frontend Engineer · OA Coding

Amazon Frontend OA:表单验证全部通过后,再追加一整行

name/phone/email规则注入、逐字段错误状态、submit拦截与原子append;原题正则条件保留待核。

题目重点:name/phone/email规则注入、逐字段错误状态、submit拦截与原子append;原题正则条件保留待核。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 调用方提供form、三个input、对应error元素、tbody和纯同步validate(values)回调。validate返回字段→错误字符串,空字符串/缺失表示通过。
  • 原姓名长度/电话格式/邮箱规则缺失,示例不编造正则。训练测试规则只为验证流程,不能当原OA条件。
  • 每次合法提交追加一行,保留原输入文本、不自动重置/去重;这些正式政策待核,调用方可配置。

解题路线

  1. 监听submit而不只click,键盘Enter也走相同验证路径;preventDefault防浏览器导航。取一次输入快照,交给明确规则层,避免边验边append。
  2. 每次同时刷新三字段error与aria-invalid,旧错误在合法修正后清除;先判全部字段无错误,才构造tr和三个td。任何一个字段失败不修改已有表行。
  3. 用textContent把文本写入cell/error,姓名含<等字符不成为HTML。原DOM selectors/顺序/测试合同需实际提供;本文参数注入不猜原ID。
  4. 规则层可以共享后端合同,但客户端校验只改善交互,服务端仍验证真实请求。邮箱/电话复杂格式不由一条回忆帖推全球通用正则。
  5. 错误应有可关联的说明,可给输入aria-describedby和错误摘要/首错焦点策略;原控件结构未知时不能伪称完成全部a11y。代码只保持字段状态与提交原子性。
  6. 异步规则若加入要给提交版本/取消与重复点击政策,不能用本文同步回调却返回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名字怎样测试?
✓已复制微信号!