There is no CSS selector targeting on textContent.
Also, as your code is currently written, it's quite easy to grab the first element which textContent
includes
this string, it will always be document.documentElement
or null
.
You should make your query a bit more strict.
You could probably build an XPath query to this very extent, but that would end up slower than iterating over all the nodes by yourself.
So if performance is an issue, a TreeWalker is the way to go.
Here is a function that will grab elements by textContent
.
It has different optional arguments which will allow you to tell
- if the query should be strict ("string === textContent" which is the default),
- a node to start the search from (defaults to
document.documentElement
)
- if you are only interested in the elements without children
function getElementByTextContent(str, partial, parentNode, onlyLast) {
var filter = function(elem) {
var isLast = onlyLast ? !elem.children.length : true;
var contains = partial ? elem.textContent.indexOf(str) > -1 :
elem.textContent === str;
if (isLast && contains)
return NodeFilter.FILTER_ACCEPT;
};
filter.acceptNode = filter; // for IE
var treeWalker = document.createTreeWalker(
parentNode || document.documentElement,
NodeFilter.SHOW_ELEMENT, {
acceptNode: filter
},
false
);
var nodeList = [];
while (treeWalker.nextNode()) nodeList.push(treeWalker.currentNode);
return nodeList;
}
// only the elements whose textContent is exactly the string
console.log('strict', getElementByTextContent('This should be found'))
// all elements whose textContent contain the string (your code)
console.log('partial', getElementByTextContent('This should', true))
// only the elements whose textContent is exactly the string and which are the last Element of the tree
console.log('strict onlyLast', getElementByTextContent('This should be found', false, null, true))
<p><span>This should be found</span></p>
<span>This should only in partial mode</span><br>
<span>This must not be found</span>
<!-- p should not be found in onlyLast mode -->