Select "Text" 节点使用查询Select或

Select "Text" node using querySelector

我正在编写一个解析器,它应该从以下 html:

中提取 "Extract This Text"
<div class="a">
    <h1>some random text</h1>
    <div class="clear"></div>
    Extract This Text
    <p></p>
    <h2></h2>
</div>

我试过使用:

document.querySelector('div.a > :nth-child(3)');

甚至使用 next sibling:

document.querySelector('div.a > :nth-child(2) + *');

但是他们都跳过它并且 returns 只跳过 "p" 元素。

我在这里看到的唯一解决方案是 select 访问前一个节点,然后使用 nextSibling 访问它。

可以querySelector select 文本节点吗?
文本节点:https://developer.mozilla.org/en-US/docs/Web/API/Text

不能,虽然我的回答不是那么权威。 (你可能已经猜到了)

你可以看看这个select text node with CSS or Is there a CSS selector for text nodes

一些冗长的解释(可能没用,英语不是我的母语,对一些单词或语法的误用感到抱歉。):

我正在学习ParentNode and since the querySelectorAll() method returning a NodeList,我想知道它是否可以select文本节点。我试过但失败了;用谷歌搜索并找到这个 post.

querySelectorAll(selectors)querySelector(selectors)中的参数是一个包含一个或多个CSS selectors的DOMString(当然不包含伪元素,否则该方法将return null) 仅适用于元素(不适用于纯文本)

如前所述,CSS 不提供文本节点选择器,因此 document.querySelector 不提供。

然而,JavaScript 确实通过 document.evaluate 方法提供了一个 XPath-解析器,它具有更多的选择器、轴和运算符,例如文本节点也是如此。

let result = document.evaluate(
  '//div[@class="a"]/div[@class="clear"]/following-sibling::text()[1]',
  document,
  null,
  XPathResult.STRING_TYPE
).stringValue;

console.log(result.trim());
<body>
  <div class="a">
    <h1>some random text</h1>
    <div class="clear"></div>
    Extract This Text
    <p></p>
    But Not This Text
    <h2></h2>
  </div>
</body>

//表示任意数量的祖先节点。
/html/body/div[@class="a"] 绝对寻址节点。

应该提到的是,CSS 查询比非常强大的 XPath 评估更高效。因此,避免在 document.querySelectorAll 也有效时过度使用 document.evaluate。保留它以用于您确实需要通过复杂表达式解析 DOM 的情况。

不直接,不。但您可以从其父级访问它:

const parent = document.querySelector('div.a')

const textNodes = [...parent.childNodes] // has childNodes inside, including text ones
  .filter(child => child.nodeType === 3) // get only text nodes
  .filter(child => child.textContent.trim()) // eliminate empty text
  .map(textNode => textNode.textContent) // extract text content

console.log(textNodes[0])
// "Extract This Text"

// make it a function
const extractText = (DOMElement) => [...DOMElement.childNodes] // has childNodes inside, including text ones
  .filter(child => child.nodeType === 3) // get only text nodes
  .filter(child => child.textContent.trim()) // eliminate empty text
  .map(textNode => textNode.textContent) // extract text content

console.log(extractText(document.querySelector('div.a'))[0])
// "Extract This Text"
}