我如何能找到DIV与某些文本?例如:

<div>
SomeText, text continues.
</div>

试图使用这样的东西:

var text = document.querySelector('div[SomeText*]').innerTEXT;
alert(text);

当然,这是行不通的。我该怎么做呢?


当前回答

使用XPath和document.evaluate(),并确保使用text()而不是。为contains()参数,否则你将匹配整个HTML,或最外层的div元素。

var headings = document.evaluate("//h1[contains(text(), 'Hello')]", document, null, XPathResult.ANY_TYPE, null );

或者忽略前导和尾随空格

var headings = document.evaluate("//h1[contains(normalize-space(text()), 'Hello')]", document, null, XPathResult.ANY_TYPE, null );

或匹配所有标签类型(div, h1, p等)

var headings = document.evaluate("//*[contains(text(), 'Hello')]", document, null, XPathResult.ANY_TYPE, null );

然后迭代

let thisHeading;
while(thisHeading = headings.iterateNext()){
    // thisHeading contains matched node
}

其他回答

由于数据属性中的文本长度没有限制,所以请使用数据属性!然后你可以使用常规的css选择器来选择你的元素(s)像OP想要的。

for (document.querySelectorAll("*")的常量元素){ element.dataset.myInnerText = element.innerText; } 文档。querySelector(“* [data-my-inner-text = '不同的文本。']”).style.color =“蓝色”; <div> . SomeText, text continue .</div> . SomeText, text continue 不同文本< div >。< / div >

理想情况下,您可以在文档加载时完成数据属性设置部分,并缩小querySelectorAll选择器的范围以提高性能。

如果你不想使用jquery或类似的东西,那么你可以试试这个:

function findByText(rootElement, text){
    var filter = {
        acceptNode: function(node){
            // look for nodes that are text_nodes and include the following string.
            if(node.nodeType === document.TEXT_NODE && node.nodeValue.includes(text)){
                 return NodeFilter.FILTER_ACCEPT;
            }
            return NodeFilter.FILTER_REJECT;
        }
    }
    var nodes = [];
    var walker = document.createTreeWalker(rootElement, NodeFilter.SHOW_TEXT, filter, false);
    while(walker.nextNode()){
       //give me the element containing the node
       nodes.push(walker.currentNode.parentNode);
    }
    return nodes;
}

//call it like
var nodes = findByText(document.body,'SomeText');
//then do what you will with nodes[];
for(var i = 0; i < nodes.length; i++){ 
    //do something with nodes[i]
} 

在数组中拥有包含文本的节点后,就可以对它们进行操作。比如提醒每个人或打印到控制台。需要注意的是,这可能并不一定会抓取div本身,这将抓取拥有您正在寻找的文本的textnode的父节点。

在2021年遇到这个问题时,我发现使用XPATH太复杂了(需要学习其他东西),不适合做一些应该相当简单的事情。

我想到了这个:

function querySelectorIncludesText (selector, text){
  return Array.from(document.querySelectorAll(selector))
    .find(el => el.textContent.includes(text));
}

用法:

querySelectorIncludesText('button', 'Send')

请注意,我决定使用包含,而不是严格的比较,因为这是我真正需要的,请随意调整。

如果你想支持所有浏览器,你可能需要这些腻子:

  /**
   * String.prototype.includes() polyfill
   * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes#Polyfill
   * @see https://vanillajstoolkit.com/polyfills/stringincludes/
   */
  if (!String.prototype.includes) {
    String.prototype.includes = function (search, start) {
      'use strict';

      if (search instanceof RegExp) {
        throw TypeError('first argument must not be a RegExp');
      }
      if (start === undefined) {
        start = 0;
      }
      return this.indexOf(search, start) !== -1;
    };
  }

使用XPath和document.evaluate(),并确保使用text()而不是。为contains()参数,否则你将匹配整个HTML,或最外层的div元素。

var headings = document.evaluate("//h1[contains(text(), 'Hello')]", document, null, XPathResult.ANY_TYPE, null );

或者忽略前导和尾随空格

var headings = document.evaluate("//h1[contains(normalize-space(text()), 'Hello')]", document, null, XPathResult.ANY_TYPE, null );

或匹配所有标签类型(div, h1, p等)

var headings = document.evaluate("//*[contains(text(), 'Hello')]", document, null, XPathResult.ANY_TYPE, null );

然后迭代

let thisHeading;
while(thisHeading = headings.iterateNext()){
    // thisHeading contains matched node
}

下面是XPath方法,但是使用了最少的XPath术语。

基于元素属性值的常规选择(用于比较):

// for matching <element class="foo bar baz">...</element> by 'bar'
var things = document.querySelectorAll('[class*="bar"]');
for (var i = 0; i < things.length; i++) {
    things[i].style.outline = '1px solid red';
}

基于元素内文本的XPath选择。

// for matching <element>foo bar baz</element> by 'bar'
var things = document.evaluate('//*[contains(text(),"bar")]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
for (var i = 0; i < things.snapshotLength; i++) {
    things.snapshotItem(i).style.outline = '1px solid red';
}

这里是不区分大小写的,因为文本更不稳定:

// for matching <element>foo bar baz</element> by 'bar' case-insensitively
var things = document.evaluate('//*[contains(translate(text(),"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz"),"bar")]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
for (var i = 0; i < things.snapshotLength; i++) {
    things.snapshotItem(i).style.outline = '1px solid red';
}