You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DOM遍历实现表单结构与值提取函数的问题求助

问题:根据表单ID生成嵌套结构的表单值对象

我需要编写一个函数,接收表单ID作为输入,返回一个代表表单结构与值的对象。给定示例HTML表单,调用函数传入form1或form2时,需返回对应嵌套结构的对象。我自己尝试了一段JavaScript代码,但无法在同一迭代中保留已更新的键并在其下添加新键,特此求助解决方法。


示例HTML代码

<!DOCTYPE html>
<html>
  <head>
    <title>Example</title>
  </head>
  <body>
    <form id="form1" ><input type="text" name="foo.bar" value="test1" /></form>
    <form id="form2" >
      <input type="text" name="foo.bar" />
      <input type="text" name="foo.baz.qux" value="test2" />
      <input type="text" name="qux" />
    </form>
  </body>
</html>

预期结果

传入form1时的返回值

{
  foo: {
    bar: 'test1',
  }
}

传入form2时的返回值

{
  foo: {
    bar: '',
    baz: {
      qux: 'test2',
    }
  },
  qux: '',
}

我尝试的代码

const Forms = document.querySelectorAll("form");
const inputs = [...Forms[0]];

const result = {};

inputs.forEach(input => {
  const val = input.value;
  const arrOfName = input.name.split('.');
  
  let prev = arrOfName[0];
  arrOfName.forEach((n, idx) => {
    let len = arrOfName.length;
    console.log("n", n, "idx", idx,"prev", prev);
    console.log("idx", idx, "prev", prev, "res", result, "current", n, "IS", !result[n]);
    if(!result[n]) {
       result[n] = {};
       prev = n;
    } else {
      result[prev][n] = {};
      prev = result[prev][n];
      console.log("result[prev]", result[prev])
    }

    console.log("Result:", result);
  })
});

解决方法

核心思路是对每个输入的name按.拆分路径,从根对象开始逐层遍历路径节点,不存在的节点就创建空对象,直到到达最后一个节点,将输入的value赋值给它(空值则保留空字符串)。

完整函数代码

function getFormData(formId) {
  // 获取目标表单,不存在则返回空对象
  const form = document.getElementById(formId);
  if (!form) return {};

  const result = {};
  // 获取表单内所有输入元素
  const inputs = form.querySelectorAll('input');

  inputs.forEach(input => {
    // 将name按.拆分为路径数组
    const nameParts = input.name.split('.');
    // 处理空值,确保返回空字符串而非undefined
    const inputValue = input.value || '';
    // 跟踪当前遍历的对象层级
    let currentLevel = result;

    // 遍历路径的前n-1个节点,构建嵌套对象
    for (let i = 0; i < nameParts.length - 1; i++) {
      const key = nameParts[i];
      // 如果当前层级没有该键,创建空对象
      if (!currentLevel[key]) {
        currentLevel[key] = {};
      }
      // 移动到下一层级
      currentLevel = currentLevel[key];
    }

    // 给最后一个路径节点赋值
    const lastKey = nameParts[nameParts.length - 1];
    currentLevel[lastKey] = inputValue;
  });

  return result;
}

// 调用示例
console.log(getFormData('form1'));
console.log(getFormData('form2'));

代码说明

  1. 获取表单:通过ID定位目标表单,避免操作无关表单
  2. 路径拆分:将输入的name属性按.拆分为数组,比如foo.baz.qux会变成['foo', 'baz', 'qux']
  3. 层级跟踪:用currentLevel变量跟踪当前操作的对象层级,确保嵌套结构正确构建
  4. 空值处理:将输入的空值转为空字符串,符合预期结果要求
  5. 赋值逻辑:遍历到路径倒数第二个节点后,将输入值赋值给最后一个节点

原代码问题分析

原代码错误地直接操作根对象result,没有跟踪当前所在的嵌套层级,导致处理多层路径(比如foo.baz.qux)时,无法正确在foo下的baz节点中添加qux,而是错误地修改根对象或上层节点,最终无法生成正确的嵌套结构。


内容的提问来源于stack exchange,提问作者Alpesh Nakrani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 11:36:06