首页 > 解决方案 > 用cheerio检测内联元素?

问题描述

是否可以使用cheerio 检测内联元素?例如:

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

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

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

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

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

标签: javascripthtmlcssnode.jscheerio

解决方案


注意:该术语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)
    }
  })
})

堆栈闪电战


推荐阅读