Javascript .querySelector 通过innerTEXT查找<div>

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37098405/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 19:55:06  来源:igfitidea点击:

Javascript .querySelector find <div> by innerTEXT

javascriptinnertextselectors-api

提问by passwd

How can I find DIV with certain text? For example:

如何找到带有特定文本的 DIV?例如:

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

Trying to use something like this:

尝试使用这样的东西:

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

But ofcourse it will not work. How can I do it?

但当然它不会工作。我该怎么做?

采纳答案by gdyrrahitis

OP's question is about plain JavaScriptand not jQuery. Although there are plenty of answers and I like @Pawan Nogariya answer, please check this alternative out.

OP 的问题是关于纯JavaScript而不是jQuery。尽管有很多答案并且我喜欢@Pawan Nogariya 的答案,但请查看此替代方案。

You can use XPATHin JavaScript. More info on the MDN article here.

您可以在 JavaScript 中使用XPATH。有关 MDN 文章的更多信息,请访问此处

The document.evaluate()method evaluates an XPATH query/expression. So you can pass XPATH expressions there, traverse into the HTML document and locate the desired element.

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

In XPATH you can select an element, by the text node like the following, whch gets the divthat has the following text node.

在 XPATH 中,您可以通过如下所示的文本节点选择一个元素,获取div具有以下文本节点的元素。

//div[text()="Hello World"]

To get an element that contains some text use the following:

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

//div[contains(., 'Hello')]

The contains()method in XPATH takes a node as first parameter and the text to search for as second parameter.

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

Check this plunk here, this is an example use of XPATH in JavaScript

在此处检查此 plunk ,这是在 JavaScript 中使用 XPATH 的示例

Here is a code snippet:

这是一个代码片段:

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";  

As you can see, I can grab the HTML element and modify it as I like.

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

回答by Niels

You could use this pretty simple solution:

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

Array.from(document.querySelectorAll('div'))
  .find(el => el.textContent === 'SomeText, text continues.');
  1. The Array.fromwill convert the NodeList to an array (there are multiple methods to do this like the spread operator or slice)

  2. The result now being an array allows for using the Array.findmethod, you can then put in any predicate. You could also check the textContent with a regex or whatever you like.

  1. Array.from将节点列表转换为数组(有多种方法来做到这一点,如传播经营者或切片)

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

Note that Array.fromand Array.findare ES2015 features. Te be compatible with older browsers like IE10 without a transpiler:

请注意,Array.fromArray.find是 ES2015 的特性。无需转译器即可与较旧的浏览器(如 IE10)兼容:

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

回答by Pawan Nogariya

Since you have asked it in javascript so you can have something like this

既然你已经在 javascript 中问过了,所以你可以有这样的东西

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

And then call it like this

然后这样称呼

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

回答by Andrew Willems

This solution does the following:

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

  • Uses the ES6 spread operator to convert the NodeList of all divs to an array.

  • Provides output if the divcontainsthe query string, not just if it exactly equalsthe query string (which happens for some of the other answers). e.g. It should provide output not just for 'SomeText' but also for 'SomeText, text continues'.

  • Outputs the entire divcontents, not just the query string. e.g. For 'SomeText, text continues' it should output that whole string, not just 'SomeText'.

  • Allows for multiple divs to contain the string, not just a single div.

  • 使用 ES6 扩展运算符将所有divs的 NodeList 转换为数组。

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

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

  • 允许多个divs 包含字符串,而不仅仅是单个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
<div>SomeText, text continues.</div>
<div>Not in this div.</div>
<div>Here is more SomeText.</div>

回答by Redu

You best see if you have a parent element of the div you are querying. If so get the parent element and perform an element.querySelectorAll("div"). Once you get the nodeListapply a filter on it over the innerTextproperty. Assume that a parent element of the div that we are querying has an idof container. You can normally access container directly from the id but let's do it the proper way.

您最好查看是否有要查询的 div 的父元素。如果是这样,获取父元素并执行element.querySelectorAll("div"). 一旦你nodeListinnerText属性上应用了一个过滤器。假设我们正在查询的 div 的父元素有一个idof container。您通常可以直接从 id 访问容器,但让我们以正确的方式进行。

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

So that's it.

就是这样了。

回答by Steve Botello

If you don't want to use jquery or something like that then you can try this:

如果你不想使用 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]
} 

Once you have the nodes in an array that contain the text you can do something with them. Like alert each one or print to console. One caveat is that this may not necessarily grab divs per se, this will grab the parent of the textnode that has the text you are looking for.

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

回答by Vigilante

Google has this as a top result for For those who need to find a node with certain text. By way of update, a nodelist is now iterable in modern browsers without having to convert it to an array.

对于需要查找具有特定文本的节点的人,Google 将此作为最佳结果。通过更新,节点列表现在可以在现代浏览器中迭代,而无需将其转换为数组。

The solution can use forEach like so.

解决方案可以像这样使用 forEach 。

var elList = document.querySelectorAll(".some .selector");
elList.forEach(function(el) {
    if (el.innerHTML.indexOf("needle") !== -1) {
        // Do what you like with el
        // The needle is case sensitive
    }
});

This worked for me to do a find/replace text inside a nodelist when a normal selector could not choose just one node so I had to filter each node one by one to check it for the needle.

当普通选择器无法仅选择一个节点时,这对我在节点列表中执行查找/替换文本很有用,因此我必须逐个过滤每个节点以检查它是否有针。

回答by Steven Spungin

Use XPath and document.evaluate(), and make sure to use text() and not . for the contains() argument, or else you will have the entire HTML, or outermost div element matched.

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

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

or ignore leading and trailing whitespace

或忽略前导和尾随空格

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

or match all tag types (div, h1, p, etc.)

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

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

Then iterate

然后迭代

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

回答by Jan Kyu Peblik

Here's the XPath approach but with a minimum of XPath jargon.

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

Regular selection based on element attribute values (for comparison):

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

// 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 selection based on text within element.

基于元素内文本的 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';
}

And here's with case-insensitivity since text is more volatile:

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

// 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';
}

回答by Pawe? Zieliński

I had similar problem.

我有类似的问题。

Function that return all element which include text from arg.

返回包含来自 arg 的文本的所有元素的函数。

This works for me:

这对我有用:

function getElementsByText(document, str, tag = '*') {
return [...document.querySelectorAll(tag)]
    .filter(
        el => (el.text && el.text.includes(str))
            || (el.children.length === 0 && el.outerText && el.outerText.includes(str)))

}

}