How to get element by innerText

JavascriptInnertext

Javascript Problem Overview


How to get tag in html page, if I know what text tag contains. E.g.:

<a ...>SearchingText</a>

Javascript Solutions


Solution 1 - Javascript

You could use xpath to accomplish this

var xpath = "//a[text()='SearchingText']";
var matchingElement = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;

You can also search of an element containing some text using this xpath:

var xpath = "//a[contains(text(),'Searching')]";

Solution 2 - Javascript

You'll have to traverse by hand.

var aTags = document.getElementsByTagName("a");
var searchText = "SearchingText";
var found;

for (var i = 0; i < aTags.length; i++) {
  if (aTags[i].textContent == searchText) {
    found = aTags[i];
    break;
  }
}

// Use `found`.

Solution 3 - Javascript

Using the most modern syntax available at the moment, it can be done very cleanly like this:

for (const a of document.querySelectorAll("a")) {
  if (a.textContent.includes("your search term")) {
    console.log(a.textContent)
  }
}

Or with a separate filter:

[...document.querySelectorAll("a")]
   .filter(a => a.textContent.includes("your search term"))
   .forEach(a => console.log(a.textContent))

Naturally, legacy browsers won't handle this, but you can use a transpiler if legacy support is needed.

Solution 4 - Javascript

You can use jQuery :contains() Selector

var element = $( "a:contains('SearchingText')" );

Solution 5 - Javascript

function findByTextContent(needle, haystack, precise) {
  // needle: String, the string to be found within the elements.
  // haystack: String, a selector to be passed to document.querySelectorAll(),
  //           NodeList, Array - to be iterated over within the function:
  // precise: Boolean, true - searches for that precise string, surrounded by
  //                          word-breaks,
  //                   false - searches for the string occurring anywhere
  var elems;

  // no haystack we quit here, to avoid having to search
  // the entire document:
  if (!haystack) {
    return false;
  }
  // if haystack is a string, we pass it to document.querySelectorAll(),
  // and turn the results into an Array:
  else if ('string' == typeof haystack) {
    elems = [].slice.call(document.querySelectorAll(haystack), 0);
  }
  // if haystack has a length property, we convert it to an Array
  // (if it's already an array, this is pointless, but not harmful):
  else if (haystack.length) {
    elems = [].slice.call(haystack, 0);
  }

  // work out whether we're looking at innerText (IE), or textContent 
  // (in most other browsers)
  var textProp = 'textContent' in document ? 'textContent' : 'innerText',
    // creating a regex depending on whether we want a precise match, or not:
    reg = precise === true ? new RegExp('\\b' + needle + '\\b') : new RegExp(needle),
    // iterating over the elems array:
    found = elems.filter(function(el) {
      // returning the elements in which the text is, or includes,
      // the needle to be found:
      return reg.test(el[textProp]);
    });
  return found.length ? found : false;;
}


findByTextContent('link', document.querySelectorAll('li'), false).forEach(function(elem) {
  elem.style.fontSize = '2em';
});

findByTextContent('link3', 'a').forEach(function(elem) {
  elem.style.color = '#f90';
});

<ul>
  <li><a href="#">link1</a>
  </li>
  <li><a href="#">link2</a>
  </li>
  <li><a href="#">link3</a>
  </li>
  <li><a href="#">link4</a>
  </li>
  <li><a href="#">link5</a>
  </li>
</ul>

Of course, a somewhat simpler way still is:

var textProp = 'textContent' in document ? 'textContent' : 'innerText';

// directly converting the found 'a' elements into an Array,
// then iterating over that array with Array.prototype.forEach():
[].slice.call(document.querySelectorAll('a'), 0).forEach(function(aEl) {
  // if the text of the aEl Node contains the text 'link1':
  if (aEl[textProp].indexOf('link1') > -1) {
    // we update its style:
    aEl.style.fontSize = '2em';
    aEl.style.color = '#f90';
  }
});

<ul>
  <li><a href="#">link1</a>
  </li>
  <li><a href="#">link2</a>
  </li>
  <li><a href="#">link3</a>
  </li>
  <li><a href="#">link4</a>
  </li>
  <li><a href="#">link5</a>
  </li>
</ul>

References:

Solution 6 - Javascript

Functional approach. Returns array of all matched elements and trims spaces around while checking.

function getElementsByText(str, tag = 'a') {
  return Array.prototype.slice.call(document.getElementsByTagName(tag)).filter(el => el.textContent.trim() === str.trim());
}

Usage

getElementsByText('Text here'); // second parameter is optional tag (default "a")

if you're looking through different tags i.e. span or button

getElementsByText('Text here', 'span');
getElementsByText('Text here', 'button');

The default value tag = 'a' will need Babel for old browsers

Solution 7 - Javascript

Simply pass your substring into the following line:

Outer HTML

document.documentElement.outerHTML.includes('substring')

Inner HTML

document.documentElement.innerHTML.includes('substring')

You can use these to search through the entire document and retrieve the tags that contain your search term:

function get_elements_by_inner(word) {
    res = []
    elems = [...document.getElementsByTagName('a')];
    elems.forEach((elem) => { 
        if(elem.outerHTML.includes(word)) {
            res.push(elem)
        }
    })
    return(res)
}

Usage:

How many times is the user "T3rm1" mentioned on this page?

get_elements_by_inner("T3rm1").length

1

How many times is jQuery mentioned?

get_elements_by_inner("jQuery").length

3

Get all elements containing the word "Cybernetic":

get_elements_by_inner("Cybernetic")

enter image description here

Solution 8 - Javascript

To get the filter method from user1106925 working in <=IE11 if needed

You can replace the spread operator with:

[].slice.call(document.querySelectorAll("a"))

and the includes call with a.textContent.match("your search term")

which works pretty neatly:

[].slice.call(document.querySelectorAll("a"))
   .filter(a => a.textContent.match("your search term"))
   .forEach(a => console.log(a.textContent))

Solution 9 - Javascript

I found the use of the newer syntax a little bit shorter compared to the others answer. So here's my proposal:

const callback = element => element.innerHTML == 'My research'

const elements = Array.from(document.getElementsByTagName('a'))
// [a, a, a, ...]

const result = elements.filter(callback)

console.log(result)
// [a]

JSfiddle.net

Solution 10 - Javascript

You can use a TreeWalker to go over the DOM nodes, and locate all text nodes that contain the text, and return their parents:

const findNodeByContent = (text, root = document.body) => {
  const treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);

  const nodeList = [];

  while (treeWalker.nextNode()) {
    const node = treeWalker.currentNode;

    if (node.nodeType === Node.TEXT_NODE && node.textContent.includes(text)) {
      nodeList.push(node.parentNode);
    }
  };

  return nodeList;
}

const result = findNodeByContent('SearchingText');

console.log(result);

<a ...>SearchingText</a>

Solution 11 - Javascript

This does the job.
Returns an array of nodes containing text.

function get_nodes_containing_text(selector, text) {
    const elements = [...document.querySelectorAll(selector)];

    return elements.filter(
      (element) =>
        element.childNodes[0]
        && element.childNodes[0].nodeValue
        && RegExp(text, "u").test(element.childNodes[0].nodeValue.trim())
    );
  }

Solution 12 - Javascript

You can do this, not sure if this is recommended but it works for me.

[... document.querySelectorAll('a')].filter(el => el.textContent.includes('sometext'));

Solution 13 - Javascript

While it's possible to get by the inner text, I think you are heading the wrong way. Is that inner string dynamically generated? If so, you can give the tag a class or -- better yet -- ID when the text goes in there. If it's static, then it's even easier.

Solution 14 - Javascript

I think you'll need to be a bit more specific for us to help you.

  1. How are you finding this? Javascript? PHP? Perl?
  2. Can you apply an ID attribute to the tag?

If the text is unique (or really, if it's not, but you'd have to run through an array) you could run a regular expression to find it. Using PHP's preg_match() would work for that.

If you're using Javascript and can insert an ID attribute, then you can use getElementById('id'). You can then access the returned element's attributes through the DOM: https://developer.mozilla.org/en/DOM/element.1.

Solution 15 - Javascript

I've just needed a way to get the element that contains a specific text and this is what I came up with.

Use document.getElementsByInnerText() to get multiple elements (multiple elements might have the same exact text), and use document.getElementByInnerText() to get just one element (first match).

Also, you can localize the search by using an element (e.g. someElement.getElementByInnerText()) instead of document.

You might need to tweak it in order to make it cross-browser or satisfy your needs.

I think the code is self-explanatory, so I'll leave it as it is.

HTMLElement.prototype.getElementsByInnerText = function (text, escape) {
    var nodes  = this.querySelectorAll("*");
    var matches = [];
    for (var i = 0; i < nodes.length; i++) {
        if (nodes[i].innerText == text) {
            matches.push(nodes[i]);
        }
    }
    if (escape) {
        return matches;
    }
    var result = [];
    for (var i = 0; i < matches.length; i++) {
        var filter = matches[i].getElementsByInnerText(text, true);
        if (filter.length == 0) {
            result.push(matches[i]);
        }
    }
    return result;
};
document.getElementsByInnerText = HTMLElement.prototype.getElementsByInnerText;

HTMLElement.prototype.getElementByInnerText = function (text) {
    var result = this.getElementsByInnerText(text);
    if (result.length == 0) return null;
    return result[0];
}
document.getElementByInnerText = HTMLElement.prototype.getElementByInnerText;

console.log(document.getElementsByInnerText("Text1"));
console.log(document.getElementsByInnerText("Text2"));
console.log(document.getElementsByInnerText("Text4"));
console.log(document.getElementsByInnerText("Text6"));

console.log(document.getElementByInnerText("Text1"));
console.log(document.getElementByInnerText("Text2"));
console.log(document.getElementByInnerText("Text4"));
console.log(document.getElementByInnerText("Text6"));

<table>
    <tr>
        <td>Text1</td>
    </tr>
    <tr>
        <td>Text2</td>
    </tr>
    <tr>
        <td>
            <a href="#">Text2</a>
        </td>
    </tr>
    <tr>
        <td>
            <a href="#"><span>Text3</span></a>
        </td>
    </tr>
    <tr>
        <td>
            <a href="#">Special <span>Text4</span></a>
        </td>
    </tr>
    <tr>
        <td>
            Text5
            <a href="#">Text6</a>
            Text7
        </td>
    </tr>
</table>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAnton KandyboView Question on Stackoverflow
Solution 1 - Javascriptcarlin.scottView Answer on Stackoverflow
Solution 2 - JavascriptAugust LilleaasView Answer on Stackoverflow
Solution 3 - Javascriptuser1106925View Answer on Stackoverflow
Solution 4 - JavascriptMouneerView Answer on Stackoverflow
Solution 5 - JavascriptDavid ThomasView Answer on Stackoverflow
Solution 6 - JavascriptPawelView Answer on Stackoverflow
Solution 7 - JavascriptCyberneticView Answer on Stackoverflow
Solution 8 - JavascriptAlkieView Answer on Stackoverflow
Solution 9 - JavascriptAmin NAIRIView Answer on Stackoverflow
Solution 10 - JavascriptOri DroriView Answer on Stackoverflow
Solution 11 - Javascriptavalanche1View Answer on Stackoverflow
Solution 12 - JavascriptRJ JaictinView Answer on Stackoverflow
Solution 13 - JavascriptZack MarrapeseView Answer on Stackoverflow
Solution 14 - JavascriptJeff MeyersView Answer on Stackoverflow
Solution 15 - JavascriptakinuriView Answer on Stackoverflow