用cheerio检测内联元素?

时间:2019-01-03 03:58:23

标签: javascript html css node.js cheerio

有可能用cheerio检测内联元素吗?例如:

<div>
  Hello
  <strong>there</strong>
  John!
</div>

这是我要检测的内联元素的示例,因为对于读者来说,strong标签很明显是该短语其余部分的延续。但是,与类似这样的东西相比:

<div>
  Jobs
  <span>Cleaner</span>
  <span>Artist</span>
</div>

这些不是完全内联的,因为对于读者来说,它们是明显分开的。

我想我要问的是,有可能使用cheerio来检测元素是否夹在其父文本之间吗?

1 个答案:

答案 0 :(得分:0)

注意:术语inline elements可能不是描述您要实现的目标的最佳方法。

我要采取的基本步骤是:

  • 使用childNodes获取子文本的节点列表 html元素。
  • 然后使用nodeType或类似方法确定节点是否为 元素或文本。
  • 然后检查文本元素在其各自的textContent或数据中是否仅包含空格字符。

使用js,可以实现这一目标的一种方式是这样的:

function markSandwichedEls(parent) {
  var children = parent.childNodes;
  for (let i = 0; i < children.length; i++) {
    if (
      children[i].nodeType === 1 &&
      children[i - 1].nodeType === 3 &&
      children[i - 1].textContent.replace(/\s/g, "").length &&
      children[i + 1].nodeType === 3 &&
      children[i + 1].textContent.replace(/\s/g, "").length
    ) {
      children[i].style.backgroundColor = "red";
    }
  }
}

document.querySelectorAll("div").forEach(div => {
  markSandwichedEls(div);
});
<div>
  Hello
  <strong>there</strong> John!
</div>

<div>
  Jobs
  <span>Cleaner</span>
  <span>Artist</span>
</div>

因此,通过应用非常相似的方法,可以像这样在cheerio中实现:

const cheerio = require('cheerio')

const $ = cheerio.load(`
<div>
  Hello
  <strong>there</strong> John!
</div>

<div>
  Jobs
  <span>Cleaner</span>
  <span>Artist</span>
</div>
`)

const divs = $('div')
divs.toArray().forEach(div => {
  div.childNodes.forEach(child => {
    if (
      child.type === 'tag' && 
      child.prev.type === 'text' &&
      child.prev.data.trim() !== '' && 
      child.next.type === 'text' &&
      child.next.data.trim() !== ''
      ) {
      console.log(child)
    }
  })
})

stackblitz