Javascript .querySelector通过innerTEXT找到<div>

pas*_*swd 69 javascript innertext selectors-api

如何找到某些文字的DIV?例如:

<div>
SomeText, text continues.
</div>
Run Code Online (Sandbox Code Playgroud)

试着用这样的东西:

var text = document.querySelector('div[SomeText*]').innerTEXT;
alert(text);
Run Code Online (Sandbox Code Playgroud)

但是当然它不起作用.我该怎么做?

gdy*_*tis 65

OP的问题是关于纯JavaScript而不是jQuery.虽然有很多答案,我喜欢@Pawan Nogariya的答案,请检查这个替代品.

您可以在JavaScript中使用XPATH.有关MDN文章的更多信息,请点击此处.

document.evaluate()方法评估XPATH查询/表达式.因此,您可以在那里传递XPATH表达式,遍历HTML文档并找到所需的元素.

在XPATH中,您可以通过文本节点选择一个元素,如下所示,其中div包含具有以下文本节点的元素.

//div[text()="Hello World"]
Run Code Online (Sandbox Code Playgroud)

要获取包含某些文本的元素,请使用以下命令:

//div[contains(., 'Hello')]
Run Code Online (Sandbox Code Playgroud)

contains()XPATH中的方法将节点作为第一个参数,将文本作为第二个参数进行搜索.

在这里检查这个插件,这是在JavaScript中使用XPATH的示例

这是一段代码:

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

console.log(thisHeading); // Prints the html element in console
console.log(thisHeading.textContent); // prints the text content in console

thisHeading.innerHTML += "<br />Modified contents";  
Run Code Online (Sandbox Code Playgroud)

如您所见,我可以抓取HTML元素并根据需要进行修改.


Nie*_*els 32

你可以用这个非常简单的解决方案:

Array.from(document.querySelectorAll('div'))
  .find(el => el.textContent === 'SomeText, text continues.');
Run Code Online (Sandbox Code Playgroud)
  1. Array.from将节点列表转换为数组(有多种方法来做到这一点,如传播经营者或切片)

  2. 结果现在是一个数组允许使用该Array.find方法,然后您可以放入任何谓词.您还可以使用正则表达式或任何您喜欢的内容检查textContent.

需要注意的是Array.fromArray.find是ES2015的特征.与没有转换器的IE10等旧版浏览器兼容:

Array.prototype.slice.call(document.querySelectorAll('div'))
  .filter(function (el) {
    return el.textContent === 'SomeText, text continues.'
  })[0];
Run Code Online (Sandbox Code Playgroud)

  • 如果您想查找多个元素,请将“find”替换为“filter”。 (7认同)

Paw*_*iya 31

既然你已经在javascript中提问它,那么你可以拥有这样的东西

function contains(selector, text) {
  var elements = document.querySelectorAll(selector);
  return Array.prototype.filter.call(elements, function(element){
    return RegExp(text).test(element.textContent);
  });
}
Run Code Online (Sandbox Code Playgroud)

然后像这样称呼它

contains('div', 'sometext'); // find "div" that contain "sometext"
contains('div', /^sometext/); // find "div" that start with "sometext"
contains('div', /sometext$/i); // find "div" that end with "sometext", case-insensitive
Run Code Online (Sandbox Code Playgroud)

  • 看起来这可行,但作为回报我只得到这个:`[object HTMLDivElement],[object HTMLDivElement]` (2认同)

Vad*_*est 19

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

想出了这个:

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

用法:

querySelectorIncludesText('button', 'Send')
Run Code Online (Sandbox Code Playgroud)

请注意,我决定使用includes并不是严格比较,因为那是我真正需要的,请随意适应。

如果您想支持所有浏览器,您可能需要这些填充:

  /**
   * 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;
    };
  }
Run Code Online (Sandbox Code Playgroud)


And*_*ems 12

该解决方案执行以下操作:

  • 使用ES6扩展运算符将all div的NodeList转换为数组。

  • 如果div 包含查询字符串,则提供输出,而不仅是与查询字符串完全相等(在其他一些答案中也会发生)。例如,它不仅应为“ SomeText”提供输出,而且还应为“ SomeText,文本继续”提供输出。

  • 输出全部div内容,而不仅仅是查询字符串。例如,对于“ SomeText,文本继续”,它应该输出整个字符串,而不仅仅是“ SomeText”。

  • 允许多个div包含字符串,而不仅仅是单个div

[...document.querySelectorAll('div')]      // get all the divs in an array
  .map(div => div.innerHTML)               // get their contents
  .filter(txt => txt.includes('SomeText')) // keep only those containing the query
  .forEach(txt => console.log(txt));       // output the entire contents of those
Run Code Online (Sandbox Code Playgroud)
<div>SomeText, text continues.</div>
<div>Not in this div.</div>
<div>Here is more SomeText.</div>
Run Code Online (Sandbox Code Playgroud)

  • 效率肯定低得可怕吗?想想最上面的“&lt;div&gt;”的“innerHTML”有多大。您应该首先过滤掉包含子项的“div”。还怀疑“document.getElementsByTagName('div')”可能更快,但我会进行基准测试以确定。 (3认同)
  • 我喜欢这个。整洁,简洁和易于理解-同时进行。 (2认同)

Red*_*edu 6

最好查看您是否有要查询的div的父元素。如果是这样,请获取父元素并执行element.querySelectorAll("div")。一旦获得nodeList应用,就对innerText属性应用过滤器。假设我们正在查询DIV的父元素具有idcontainer。通常,您可以直接从ID访问容器,但请以正确的方式进行操作。

var conty = document.getElementById("container"),
     divs = conty.querySelectorAll("div"),
    myDiv = [...divs].filter(e => e.innerText == "SomeText");
Run Code Online (Sandbox Code Playgroud)

就是这样了。


Ste*_*llo 5

如果你不想使用 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]
} 
Run Code Online (Sandbox Code Playgroud)

一旦您在包含文本的数组中拥有节点,您就可以对它们做一些事情。就像提醒每个人或打印到控制台一样。一个警告是,这本身可能不一定会抓取 div,这将抓取具有您正在查找的文本的 textnode 的父级。