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

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

试图使用这样的东西:

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

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


当前回答

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

你可以在JavaScript中使用XPATH。更多关于MDN文章的信息请点击这里。

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

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

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

要获得一个包含一些文本的元素,使用以下方法:

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

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

看这里,这是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";  

如您所见,我可以获取HTML元素并按我喜欢的方式修改它。

其他回答

因为你已经在javascript中要求它,所以你可以有这样的东西

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

然后像这样叫它

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

使用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
}

这里已经有很多很棒的解决方案了。但是,为了提供一个更精简的解决方案,并且更符合querySelector行为和语法的思想,我选择了一个用几个原型函数扩展Object的解决方案。这两个函数都使用正则表达式来匹配文本,但是,字符串可以作为松散搜索参数提供。

简单地实现以下函数:

// find all elements with inner text matching a given regular expression
// args: 
//      selector: string query selector to use for identifying elements on which we 
//                should check innerText
//      regex: A regular expression for matching innerText; if a string is provided,
//             a case-insensitive search is performed for any element containing the string.
Object.prototype.queryInnerTextAll = function(selector, regex) {
    if (typeof(regex) === 'string') regex = new RegExp(regex, 'i'); 
    const elements = [...this.querySelectorAll(selector)];
    const rtn = elements.filter((e)=>{
        return e.innerText.match(regex);
    });
    
    return rtn.length === 0 ? null : rtn
}

// find the first element with inner text matching a given regular expression
// args: 
//      selector: string query selector to use for identifying elements on which we 
//                should check innerText
//      regex: A regular expression for matching innerText; if a string is provided,
//             a case-insensitive search is performed for any element containing the string.
Object.prototype.queryInnerText = function(selector, text){
    return this.queryInnerTextAll(selector, text)[0];
}

实现了这些函数后,现在可以进行如下调用:

document.queryInnerTextAll('div.link', 'go'); This would find all divs containing the link class with the word go in the innerText (eg. Go Left or GO down or go right or It's Good) document.queryInnerText('div.link', 'go'); This would work exactly as the example above except it would return only the first matching element. document.queryInnerTextAll('a', /^Next$/); Find all links with the exact text Next (case-sensitive). This will exclude links that contain the word Next along with other text. document.queryInnerText('a', /next/i); Find the first link that contains the word next, regardless of case (eg. Next Page or Go to next) e = document.querySelector('#page'); e.queryInnerText('button', /Continue/); This performs a search within a container element for a button containing the text, Continue (case-sensitive). (eg. Continue or Continue to Next but not continue)

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

Array.from(document.querySelectorAll('div'))
  .find(el => el.textContent === 'SomeText, text continues.');

from将把NodeList转换为一个数组(有多种方法可以做到这一点,如展开操作符或切片) 结果现在是一个数组,允许使用数组。Find方法,然后可以放入任何谓词。你也可以用正则表达式或任何你喜欢的东西检查textContent。

注意Array.from和Array.from。find是ES2015的特性。在没有转译器的情况下,与IE10等旧浏览器兼容:

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

下面是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';
}