我如何处理 HTMLCollection {}?

How do I process HTMLCollection {}?

我正在使用 JSDOM 设置 html 进行处理。

async function processHtml(input) {
  const dom = new JSDOM(input)
  const tables = dom.window.document.getElementsByTagName('tbody')
  for (let x of tables) {
    
    if (x.getElementsByTagName('tr').length === 1) {
      const test = [...x.getElementsByTagName('tr')]
      console.log("Line 32:", test)
    } else {
      console.log("Line 32:", x.getElementsByTagName('tr').length)
    }
  }
}

我从这个算法中得到的是:

Line 32: HTMLTableRowElement {}
Line 32: 11
Line 32: 10
Line 32: 10
Line 32: HTMLTableRowElement {}
Line 32: HTMLTableRowElement {}
Line 32: 11
Line 32: 12
Line 32: 3
Line 32: HTMLTableRowElement {} 

我卡住了。这些不是常规对象? 我该如何处理它们?

备注

如何在 HTMLTableRowElement { } 上使用 DOM 方法?

更新一:改变函数

我想在这里看看我在做什么。

async function processHtml(input) {
  const dom = new JSDOM(input)
  const tables = dom.window.document.getElementsByTagName('tbody')

  Object.keys(tables).forEach(x => console.log(tables[x]))
}

这个函数returns:

HTMLTableSectionElement {}
HTMLTableSectionElement {}
HTMLTableSectionElement {}
HTMLTableSectionElement {}
HTMLTableSectionElement {}
HTMLTableSectionElement {}
HTMLTableSectionElement {}
HTMLTableSectionElement {}
HTMLTableSectionElement {}
HTMLTableSectionElement {}

看来这将成为一种模式。 我不知道有什么工具可以帮助我正确处理这个问题。

我们将不胜感激。谢谢。

更新 2:如果其他人觉得这个问题有用

这个算法让我更接近我正在寻找的解决方案。谢谢 接受的答案。

async function processHtml(input) {
  const dom = new JSDOM(input)
  Array.from(dom.window.document.querySelectorAll('table tbody')).forEach((tbody, i) => {
    if (i === 4 || i === 5) {
      console.log(`========= ${i} ============`)
      Array.from(tbody.querySelectorAll('td')).forEach((td, j) => {
        if (j === 0 || j === 1){
          console.log(`[${j}]`, td.innerHTML)
        }
      })
      console.log('===========================')
    }
  })

let x of tables 将遍历 all 对象的可枚举属性的值,包括 length 之类的东西。将 of 切换为 in 以获取名称。

您只需要数字索引。使用常规 for (let i = 0; i < x.length; i++) 循环。

你有一些选择。首先,如果你想用它们的默认迭代行为遍历它们,你需要像你一样使用 for of

如果您还想使用数组方法,可以通过以下方式将 NodeListHTMLLiveCollection 转换为数组:

  • 旧方法: Array.prototype.slice.call(...)
  • es6: Array.from(...)
Array.from(document.querySelectorAll('table tbody')).forEach(tbody=>{
    //do something with tbody
    Array.from(tbody.querySelectorAll("tr")).forEach(tr => {
        //do something with tr
    })
})

在上面的示例中,将 document 更改为 dom.window.document,如果您愿意,可以使用 getElementsByTagName 方法。

getElementsByClassNamegetElementsByTagName return live HTMLCollection,意思是 returned 对象类似于数组但不是数组,并且会随着您的更改而更新DOM。 querySelectorAll returns a NodeList,类似于 HTMLCollection 但不更新。它们都有像 item 这样的传统方法来通过索引获取节点,但我建议先将它们转换为数组。

在上面的示例中,除了内部 forEach 循环,您还可以使用 Array.from(tbody.childNodes) 并检查给定项 tagName 属性 是否等于TR 或否,并相应地进行。

根据您的喜好,您有太多选择,我建议通过 MDN 获取 Node and Element 文档。