我如何能找到DIV与某些文本?例如:
<div>
SomeText, text continues.
</div>
试图使用这样的东西:
var text = document.querySelector('div[SomeText*]').innerTEXT;
alert(text);
当然,这是行不通的。我该怎么做呢?
我如何能找到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
}
其他回答
你可以使用这个非常简单的解决方案:
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];
我也有类似的问题。
函数返回包含arg文本的所有元素。
这对我来说很管用:
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)))
}
使用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
}
如果你不想使用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的父节点。
这里已经有很多很棒的解决方案了。但是,为了提供一个更精简的解决方案,并且更符合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)