首页 > 解决方案 > 来自 HTML 的嵌套对象?

问题描述

我有这个结构对象:

let obj = {
  hello: {
    the: {
      world: {
        very: 'cool'
      }
    },
    other: 'universe'
  },
  bye: 'bye'
}

我为此生成了一个 html,我可以在其中编辑键和值:

<div id="object">
<input name="hello" id="hello" class="block nested" type="text" value="hello">
<div id="object">
    <input name="the" id="the" class="block nested" type="text" value="the">
    <div id="object">
        <input name="world" id="world" class="block nested" type="text" value="world">
        <div id="pair">
            <input name="very" id="very" type="text" value="very">
            <input id="cool" type="text" value="cool">
        </div>
    </div>
</div>
<div id="pair">
    <input name="other" id="other" type="text" value="other">
    <input id="universe" type="text" value="universe">
</div>

我尝试修改每个输入,并使用更新的键和值重新生成相同的对象结构。

我试过这个:

let objUpdated = {};
let subObject = {};
const loopIntoNodes = (nodeArray) => {
  Array.from(nodeArray).forEach((subNode) => {
      if (subNode.id === 'object') {
        subObject = {[subNode.firstChild.name]: {}}
        objUpdated = {...objUpdated, ...subObject};
        loopIntoNodes(subNode.firstChild.nextSibling.childNodes);
      }
      else if (subNode.id === 'pair') {
        objUpdated = {...objUpdated, ...{[subNode.firstChild.name]:subNode.firstChild.nextSibling.value}};
      }
  });
  console.log(objUpdated);
}

  const body = document.querySelector('body div');
  loopIntoNodes(body.childNodes);

但是我找不到从 html 中正确重新组装嵌套对象的逻辑。我知道当我有一个输入然后是一个 id 对象 div,下一个值必须是下一个 div 的键,如果我有一个 div 对 id,它必须是键和值。

标签: javascripthtmlobject

解决方案


首先,您应该用其他东西更改 id,data例如,您可以使用属性。div然后,您可以创建递归函数,该函数将采用一个根元素,然后基于inputs它在内部构建嵌套结构。

const element = document.querySelector('body > div');

function toObject(element, result = {}) {
  const divs = element.querySelectorAll(':scope > div');
  const inputs = element.querySelectorAll(':scope > input');
  const [key, value] = [...inputs].map(e => e.dataset.id);

  if (element.dataset.id == 'pair') {
    result[key] = value
  }

  divs.forEach(div => {
    const id = div.dataset.id;

    if (!result[key]) {
      result[key] = {}
    }

    toObject(div, result[key])
  })

  return result;
}

const result = toObject(element);
console.log(result)
<div data-id="object">
  <input name="hello" data-id="hello" class="block nested" type="text" value="hello">

  <div data-id="object">
    <input name="the" data-id="the" class="block nested" type="text" value="the">
    <div data-id="object">
      <input name="world" data-id="world" class="block nested" type="text" value="world">
      <div data-id="pair">
        <input name="very" data-id="very" type="text" value="very">
        <input data-id="cool" type="text" value="cool">
      </div>
    </div>
  </div>

  <div data-id="pair">
    <input name="other" data-id="other" type="text" value="other">
    <input data-id="universe" type="text" value="universe">
  </div>
</div>


推荐阅读