我如何处理 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
。
如果您还想使用数组方法,可以通过以下方式将 NodeList
或 HTMLLiveCollection
转换为数组:
- 旧方法:
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
方法。
getElementsByClassName
和 getElementsByTagName
return live HTMLCollection
,意思是 returned 对象类似于数组但不是数组,并且会随着您的更改而更新DOM。 querySelectorAll
returns a NodeList
,类似于 HTMLCollection
但不更新。它们都有像 item
这样的传统方法来通过索引获取节点,但我建议先将它们转换为数组。
在上面的示例中,除了内部 forEach
循环,您还可以使用 Array.from(tbody.childNodes)
并检查给定项 tagName
属性 是否等于TR
或否,并相应地进行。
我正在使用 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
。
如果您还想使用数组方法,可以通过以下方式将 NodeList
或 HTMLLiveCollection
转换为数组:
- 旧方法:
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
方法。
getElementsByClassName
和 getElementsByTagName
return live HTMLCollection
,意思是 returned 对象类似于数组但不是数组,并且会随着您的更改而更新DOM。 querySelectorAll
returns a NodeList
,类似于 HTMLCollection
但不更新。它们都有像 item
这样的传统方法来通过索引获取节点,但我建议先将它们转换为数组。
在上面的示例中,除了内部 forEach
循环,您还可以使用 Array.from(tbody.childNodes)
并检查给定项 tagName
属性 是否等于TR
或否,并相应地进行。