jQuery API

.has()

.has( selector ) Returns: jQuery

Description: Reduce the set of matched elements to those that have a descendant that matches the selector or DOM element.

  • version added: 1.4.has( selector )

    selectorA string containing a selector expression to match elements against.

  • version added: 1.4.has( contained )

    containedA DOM element to match elements against.

Given a jQuery object that represents a set of DOM elements, the .has() method constructs a new jQuery object from a subset of the matching elements. The supplied selector is tested against the descendants of the matching elements; the element will be included in the result if any of its descendant elements matches the selector.

Consider a page with a nested list as follows:

 <ul>
  <li>list item 1</li>
  <li>list item 2
    <ul>
      <li>list item 2-a</li>
      <li>list item 2-b</li>
    </ul>
  </li>
  <li>list item 3</li>
  <li>list item 4</li>
</ul>

We can apply this method to the set of list items as follows:

$('li').has('ul').css('background-color', 'red');

The result of this call is a red background for item 2, as it is the only <li> that has a <ul> among its descendants.

Example:

Check if an element is inside another.

<!DOCTYPE html>
<html>
<head>
  <style>
  .full { border: 1px solid red; }
</style>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
  
<ul><li>Does the UL contain an LI?</li></ul>

<script>
  $("ul").append("<li>" + ($("ul").has("li").length ? "Yes" : "No") + "</li>");
  $("ul").has("li").addClass("full");
</script>

</body>
</html>

Demo:

Support and Contributions

Need help with .has() or have a question about it? Visit the jQuery Forum or the #jquery channel on irc.freenode.net.

Think you've discovered a jQuery bug related to .has()? Report it to the jQuery core team.

Found a problem with this documentation? Report it on the GitHub issue tracker

  • http://fgribreau.com/ Francois-Guillaume Ribreau

    $(“li”,”ul”).length seems faster than $(“ul”).has(“li”).length :

    (from the jQuery 1.4rc1 source code)
    has: function( target ) {
    var targets = jQuery( target );//gets ALL LI elements
    return this.filter(function() {//and then, loop on every LI elements.
    for ( var i = 0, l = targets.length; i < l; i++ ) {
    if ( jQuery.contains( this, targets[i] ) ) {
    return true;
    }
    }
    });
    }

    • http://ejohn.org/ John Resig

      It’s not meant to be used like that, primarily – it’s meant to be used like the :has() selector. For example instead of doing: $(“ul:has(li)”).addClass(“full”); you can do: $(“ul”).has(“li”).addClass(“full”);

      • http://fgribreau.com/ Francois-Guillaume Ribreau

        Oh Ok! I got the point now :)
        But I think the description should be updated.

        • http://www.learningjquery.com/ Karl Swedberg

          Yeah, the description wasn’t terribly clear. I’ve updated it. Hope that helps.

  • http://profiles.yahoo.com/u/NXLZE2HNMJGGNEWUOAK6IMOYTY Adam B

    Is this distinct from .find() ? If so how?

    • http://www.learningjquery.com/ Karl Swedberg

      Yes, this is different from .find(). For example, $(‘div’).has(‘p’) selects all divs that have a paragraph as a descendant while $(‘div’).find(‘p’) selects all paragraphs that are descendants of a div.

  • http://www.piromanos.com/ Paco Lopez

    So, $(“ul”).has(“li”) is faster than $(“ul:has(li)”) ?

    I suppose it is, compute two simple selectors is faster than one complex selector.

  • Anonymous

    I use the jquery treeview plugin (from Jörn Zaefferer) with jquery 1.2.6 version but yesterday I updated the version and the plugin crashed… I found the “bug”:

    this.filter(“:has(>ul:hidden)”)
    .addClass(CLASSES.expandable)
    .replaceClass(CLASSES.last, CLASSES.lastExpandable);

    so I tested the following alert: (under 1.2.6 and 1.4 version)
    alert(this.filter(“:has(>ul:hidden)”).length);
    alert(this.filter(“:has(>ul:visible)”).length);

    I had 4 list element in it 1-1 ul (in 3 cases the ul is display:block and in 1 case display:none)

    the result under 1.2.6:
    1
    3
    that’s OK

    the result under 1.4:
    4
    4

    what’s wrong?

    maybe :hidden and :visible doesn’t work?

    thanks and sorry for my english.

    • http://www.learningjquery.com/ Karl Swedberg

      This isn’t the appropriate venue for bug reports or support requests. Please direct this issue to http://forum.jquery.com/using-jquery-plugins

      Thanks!

      • Anonymous

        sorry, I didn’t know, I just realized it…

  • http://control-v.net/ Brant

    If you want to filter the selected elements by those which do NOT have descendants matching a selector, wrap your :has() in a :not() like so: $(“li:not(:has(p))”);

  • rv4wd

    This has() function differs slightly from the has selector:
    $('ul:has(>li)') works, $('ul').has('>li') does not work

    • bugaga

      try:
      $(‘ul’).has(‘li’)

  • Krishna

    $(“div:has(img)”) works but not $(“div”).has(img)”. both are supposed to return same results? any difference between :has and has()?

    Thanks,
    Kris

    • Tom K

      i think it should look like this:
      $(“div”).has(“img”)

      pay attention to the quotes!

    • http://css-plus.com Jamy Golden

      You should add quotes around the content within has().
      $(“div”).has(img)
      Should be
      $(“div”).has(“img”)

  • Max Roald Eckardt

    For finding common parent elements for both anchor node and focus node of a selection range U can use:

    $(document.getSelection().getRangeAt(0).startContainer).parents().has(document.getSelection().getRangeAt(0).endContainer)

  • Chris

    Oh wait I figured it out.

    $(this).parent().parent().find(“.report_icon”).slideToggle(500);

    This works for me.

    Cheers everyone for your great examples that helped me finally get this.

  • ihazcooki3z

    Why is that, if I use $(“div#divName:has('a')”) i get the right results, but if I use $(“div#divName”).has(“a”) it returns with no element (length = 0)

    • http://www.learningjquery.com/ Karl Swedberg

      Not sure. I don't have the same problem. Could you direct your question to http://forum.jquery.com/ and provide a simplified test case on jsfiddle.net that people can look at?

  • http://www.learningjquery.com/ Karl Swedberg

    Not sure. I don't have the same problem. Could you direct your question to http://forum.jquery.com/ and provide a simplified test case on jsfiddle.net that people can look at?

  • Deepak

    In ” .has( contained ) ” , can contained be a set (Array) of DOM elements ?