Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/91.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何正确生成这些嵌套HTML列表的数据结构_Javascript_Html_Algorithm_Css Selectors - Fatal编程技术网

Javascript 如何正确生成这些嵌套HTML列表的数据结构

Javascript 如何正确生成这些嵌套HTML列表的数据结构,javascript,html,algorithm,css-selectors,Javascript,Html,Algorithm,Css Selectors,假设我有如下HTML: <body> <div> <div> <div> <p> <b>Title A</b> <p> <table> <tbody> <tr> <td>Item 1:<

假设我有如下HTML:

<body>
  <div>
    <div>
      <div>
        <p>
          <b>Title A</b>
        <p>
        <table>
          <tbody>
            <tr>
              <td>Item 1:</td>
            </tr>
            <tr>
              <td>
                <p><b>Content title 1.1</b></p>
                <p>Content 1.1</p>
                <p>Content 1.1b</p>
                <p>Content 1.1c</p>
                <p>Content 1.1d (arbitrary paragraph number follows content title)</p>
                <p>Content ...</p>
                <p><b>Content title 1.2</b></p>
                <p>Content 1.2</p>
                <p>Content 1.2b</p>
                <p>Content 1.2...</p>
                ...
              </td>
            </tr>
            <tr>
              <td>Item 2:</td>
            </tr>
            <tr>
              <td>
                <p><b>Content title 2.1</b></p>
                <p>Content 2.1</p>
                <p><b>Content title 2.2</b></p>
                <p>Content 2.2</p>
                ...
              </td>
            </tr>
            ...
          </tbody>
        </table>

        <p>
          <b>Title B</b>
        <p>
        <table>
          <tbody>
            <tr>
              <td>Item 1b:</td>
            </tr>
            <tr>
              <td>
                <p><b>Content title 1b.1</b></p>
                <p>Content 1b.1</p>
                <p><b>Content title 1b.2</b></p>
                <p>Content 1b.2</p>
                ...
              </td>
            </tr>
            <tr>
              <td>Item 2b:</td>
            </tr>
            <tr>
              <td>
                <p><b>Content title 2b.1</b></p>
                <p>Content 2b.1</p>
                <p><b>Content title 2b.2</b></p>
                <p>Content 2b.2</p>
                ...
              </td>
            </tr>
            ...
          </tbody>
        </table>

        ...
var titles = document.querySelector(
  'body > div > div > div > p > b'
)
var items = document.querySelector(
  'body > div > div > div > table tr:nth-child(odd) td'
)
var itemContentTitles = document.querySelector(
  'body > div > div > div > table tr:nth-child(even) p b'
)
// somehow select all children after the content title, 
// up until the next content title or til 
// there are no more elements.
var itemContents = document.querySelector(
  'body > div > div > div > table tr:nth-child(even) p'
)
[
  {
    text: 'Title A',
    items: [
      {
        text: 'Item 1',
        items: [
          {
            text: 'Content title 1.1',
            items: [
              { text: 'Content 1.1' },
              { text: 'Content 1.1b' },
              { text: 'Content 1.1c' },
              { text: 'Content 1.1d' }
              ...
            ]
          },
          {
            text: 'Content title 1.2',
            items: [
              { text: 'Content 1.2' },
              { text: 'Content 1.2b' },
              { text: 'Content 1.2...' }
              ...
            ]
          }
        ]
      },
      {
        text: 'Item 2',
        items: [
          {
            text: 'Content title 2.1',
            items: [
              { text: 'Content 2.1' }
              ...
            ]
          },
          {
            text: 'Content title 2.2',
            items: [
              { text: 'Content 2.2' }
              ...
            ]
          }
        ]
      }
    ]
  },

  {
    text: 'Title B',
    items: [
      ...
    ]
  }
]
一旦这些数组中有了数据,主要问题是如何正确地将它们编织在一起。您希望的最终结果如下所示:

<body>
  <div>
    <div>
      <div>
        <p>
          <b>Title A</b>
        <p>
        <table>
          <tbody>
            <tr>
              <td>Item 1:</td>
            </tr>
            <tr>
              <td>
                <p><b>Content title 1.1</b></p>
                <p>Content 1.1</p>
                <p>Content 1.1b</p>
                <p>Content 1.1c</p>
                <p>Content 1.1d (arbitrary paragraph number follows content title)</p>
                <p>Content ...</p>
                <p><b>Content title 1.2</b></p>
                <p>Content 1.2</p>
                <p>Content 1.2b</p>
                <p>Content 1.2...</p>
                ...
              </td>
            </tr>
            <tr>
              <td>Item 2:</td>
            </tr>
            <tr>
              <td>
                <p><b>Content title 2.1</b></p>
                <p>Content 2.1</p>
                <p><b>Content title 2.2</b></p>
                <p>Content 2.2</p>
                ...
              </td>
            </tr>
            ...
          </tbody>
        </table>

        <p>
          <b>Title B</b>
        <p>
        <table>
          <tbody>
            <tr>
              <td>Item 1b:</td>
            </tr>
            <tr>
              <td>
                <p><b>Content title 1b.1</b></p>
                <p>Content 1b.1</p>
                <p><b>Content title 1b.2</b></p>
                <p>Content 1b.2</p>
                ...
              </td>
            </tr>
            <tr>
              <td>Item 2b:</td>
            </tr>
            <tr>
              <td>
                <p><b>Content title 2b.1</b></p>
                <p>Content 2b.1</p>
                <p><b>Content title 2b.2</b></p>
                <p>Content 2b.2</p>
                ...
              </td>
            </tr>
            ...
          </tbody>
        </table>

        ...
var titles = document.querySelector(
  'body > div > div > div > p > b'
)
var items = document.querySelector(
  'body > div > div > div > table tr:nth-child(odd) td'
)
var itemContentTitles = document.querySelector(
  'body > div > div > div > table tr:nth-child(even) p b'
)
// somehow select all children after the content title, 
// up until the next content title or til 
// there are no more elements.
var itemContents = document.querySelector(
  'body > div > div > div > table tr:nth-child(even) p'
)
[
  {
    text: 'Title A',
    items: [
      {
        text: 'Item 1',
        items: [
          {
            text: 'Content title 1.1',
            items: [
              { text: 'Content 1.1' },
              { text: 'Content 1.1b' },
              { text: 'Content 1.1c' },
              { text: 'Content 1.1d' }
              ...
            ]
          },
          {
            text: 'Content title 1.2',
            items: [
              { text: 'Content 1.2' },
              { text: 'Content 1.2b' },
              { text: 'Content 1.2...' }
              ...
            ]
          }
        ]
      },
      {
        text: 'Item 2',
        items: [
          {
            text: 'Content title 2.1',
            items: [
              { text: 'Content 2.1' }
              ...
            ]
          },
          {
            text: 'Content title 2.2',
            items: [
              { text: 'Content 2.2' }
              ...
            ]
          }
        ]
      }
    ]
  },

  {
    text: 'Title B',
    items: [
      ...
    ]
  }
]
问题是,如何从使用一些基本CSS选择器选择的项目数组(因此不需要大量定制编程)过渡到这个嵌套的JSON数据结构

似乎您应该能够遍历每个列表中的每个项,然后检查它与父项的关系。当然,我们会指定哪个列表应该作为子列表应用于其他列表。因此,我们可以这样做:

function assignChildren(parents, children) {

}
然后做:

assignChildren(titles, items)
但我们可能实际上必须从下至上开始,并做到:

assignChildren(itemContentTitles, itemContents)
这里的棘手问题是如何解决知道哪个
itemContents
项目属于哪个
itemContentTitle
的问题。我们从HTML中知道它们之间的关系。基本上是这样的:

itemContent
  .parentNode
  .parentNode
  .previousElementSibling
    .firstElementChild
      .firstElementChild
但问题是,我们如何才能通用地解决这个问题,这样就不需要编写自定义代码了。也就是说,您只需这样做:

assignChildren(itemContentTitles, itemContents)
…并获取嵌套的JSON结构。它似乎可以像这样工作:

<body>
  <div>
    <div>
      <div>
        <p>
          <b>Title A</b>
        <p>
        <table>
          <tbody>
            <tr>
              <td>Item 1:</td>
            </tr>
            <tr>
              <td>
                <p><b>Content title 1.1</b></p>
                <p>Content 1.1</p>
                <p>Content 1.1b</p>
                <p>Content 1.1c</p>
                <p>Content 1.1d (arbitrary paragraph number follows content title)</p>
                <p>Content ...</p>
                <p><b>Content title 1.2</b></p>
                <p>Content 1.2</p>
                <p>Content 1.2b</p>
                <p>Content 1.2...</p>
                ...
              </td>
            </tr>
            <tr>
              <td>Item 2:</td>
            </tr>
            <tr>
              <td>
                <p><b>Content title 2.1</b></p>
                <p>Content 2.1</p>
                <p><b>Content title 2.2</b></p>
                <p>Content 2.2</p>
                ...
              </td>
            </tr>
            ...
          </tbody>
        </table>

        <p>
          <b>Title B</b>
        <p>
        <table>
          <tbody>
            <tr>
              <td>Item 1b:</td>
            </tr>
            <tr>
              <td>
                <p><b>Content title 1b.1</b></p>
                <p>Content 1b.1</p>
                <p><b>Content title 1b.2</b></p>
                <p>Content 1b.2</p>
                ...
              </td>
            </tr>
            <tr>
              <td>Item 2b:</td>
            </tr>
            <tr>
              <td>
                <p><b>Content title 2b.1</b></p>
                <p>Content 2b.1</p>
                <p><b>Content title 2b.2</b></p>
                <p>Content 2b.2</p>
                ...
              </td>
            </tr>
            ...
          </tbody>
        </table>

        ...
var titles = document.querySelector(
  'body > div > div > div > p > b'
)
var items = document.querySelector(
  'body > div > div > div > table tr:nth-child(odd) td'
)
var itemContentTitles = document.querySelector(
  'body > div > div > div > table tr:nth-child(even) p b'
)
// somehow select all children after the content title, 
// up until the next content title or til 
// there are no more elements.
var itemContents = document.querySelector(
  'body > div > div > div > table tr:nth-child(even) p'
)
[
  {
    text: 'Title A',
    items: [
      {
        text: 'Item 1',
        items: [
          {
            text: 'Content title 1.1',
            items: [
              { text: 'Content 1.1' },
              { text: 'Content 1.1b' },
              { text: 'Content 1.1c' },
              { text: 'Content 1.1d' }
              ...
            ]
          },
          {
            text: 'Content title 1.2',
            items: [
              { text: 'Content 1.2' },
              { text: 'Content 1.2b' },
              { text: 'Content 1.2...' }
              ...
            ]
          }
        ]
      },
      {
        text: 'Item 2',
        items: [
          {
            text: 'Content title 2.1',
            items: [
              { text: 'Content 2.1' }
              ...
            ]
          },
          {
            text: 'Content title 2.2',
            items: [
              { text: 'Content 2.2' }
              ...
            ]
          }
        ]
      }
    ]
  },

  {
    text: 'Title B',
    items: [
      ...
    ]
  }
]
itemContents
元素(子列表项之一)开始。然后我们知道找到父项的父选择器。因此,以某种方式向上、向后和向下导航,以匹配该项的父选择器。这就是它开始变得棘手的地方,我很难看到如何在基本上不扫描整个DOM和检查每个项的完整生成的选择器路径的情况下完成它(诸如此类的事情)。想知道如何做到这一点。不一定要有超高的性能,但良好的性能总是一个加号

这样做的原因是,这样做只需要指定嵌套JSON结构不同部分的选择器,以及每个选择器与其父级的关系。在DOM中导航时,不必为每个选择器编写自定义代码

主要问题是在上述场景中,如何将孩子编织到父母身上