405

Can anyone tell me if it's possible to find an element based on its content rather than by an ID or class?

I am attempting to find elements that don't have distinct classes or IDs. (Then I then need to find that element's parent.)

isherwood
  • 58,414
  • 16
  • 114
  • 157
sisko
  • 9,604
  • 20
  • 67
  • 139
  • 1
    http://api.jquery.com/category/selectors/ – Felix Kling Sep 06 '11 at 14:56
  • 1
    Possible duplicate of [How do I select a span containing a specific text value, using jquery?](https://stackoverflow.com/questions/9424417/how-do-i-select-a-span-containing-a-specific-text-value-using-jquery) – AncientSwordRage Aug 09 '17 at 09:46

8 Answers8

566

You can use the :contains selector to get elements based on their content.

Demo here

$('div:contains("test")').css('background-color', 'red');
<div>This is a test</div>
<div>Another Div</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
Gleb Kemarsky
  • 10,160
  • 7
  • 43
  • 68
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
  • 5
    Great, but it is case sensitive. Is there anyway we can do a case insensitive search? – Dipu Raj Apr 04 '12 at 09:36
  • 142
    @DipuRaj: You'd have to use [`.filter`](http://api.jquery.com/filter/) instead. `$('div').filter(function(){ return $(this).text().toLowerCase() === 'test';})` – gen_Eric Apr 04 '12 at 13:06
  • 6
    Yes, please use the appraoch **@RocketHazmat** uses, say you have 5 elements all **prefixed with 'Register Contract'** and each has a number suffix. You'll end up **selecting them all**, when in reality you only want the element with text: **'Register Contract 26'**. – Riveascore Oct 14 '14 at 16:45
  • 1
    Although :contains is case sensitive, it worked for me because I passed the exact text string to be find. – Francisco Quintero Jul 06 '15 at 15:26
  • 2
    In case it helps someone else who likes to use spaces in their parens, the following does **not** work: `$('div:contains( "test" )').css('background-color', 'red');` – M Katz Mar 31 '20 at 05:18
  • 2
    This is not working if you are running it all over the the page because all divs will contain the wanted text. Highly recommand to check there is no more other child. – Maxime Culea Apr 26 '20 at 10:25
  • 2
    Not good. In case of nested `div`s, this will return all `div`s until the root div i.e. from where query started. – SimpleGuy Sep 06 '20 at 08:58
  • 1
    `Uncaught DOMException: Document.querySelector: 'div:contains("test")' is not a valid selector` – Ross Presser Feb 18 '21 at 16:49
  • It worked for me without **"** : `$('div:contains(test)').css('background-color', 'red');` – Yongstephi Nov 20 '21 at 18:48
108

In jQuery documentation it says:

The matching text can appear directly within the selected element, in any of that element's descendants, or a combination

Therefore it is not enough that you use :contains() selector, you also need to check if the text you search for is the direct content of the element you are targeting for, something like that:

function findElementByText(text) {
    var jSpot = $("b:contains(" + text + ")")
                .filter(function() { return $(this).children().length === 0;})
                .parent();  // because you asked the parent of that element

    return jSpot;
}
informatik01
  • 16,038
  • 10
  • 74
  • 104
yoav barnea
  • 5,836
  • 2
  • 22
  • 27
  • 3
    This solution might fail in following scenario: `
  • Hello World, How Are You. `. Here if `How` is being searched the condition will fail I think.
  • – me_digvijay Sep 25 '17 at 18:59