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.min.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:

Comments

  • Support requests, bug reports, and off-topic comments will be deleted without warning.

  • Please do post corrections or additional examples for .has() below. We aim to quickly move corrections into the documentation.
  • If you need help, post at the forums or in the #jquery IRC channel.
  • Report bugs on the bug tracker or the jQuery Forum.
  • Discussions about the API specifically should be addressed in the Developing jQuery Core forum.
  • 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
  • You should add quotes around the content within has().
    $("div").has(img)
    Should be
    $("div").has("img")
  • Tom K
    i think it should look like this:
    $("div").has("img")

    pay attention to the quotes!
  • You are great guys, i get know the ":has(>...)" first time,
    maybe Resig should make a ":child(...)" to contrast ":has(...)",
    just like ".the_parent > .the_child" contrasting ".the_parent .the_child".

    Similarly , we could do this:
    .find('> td > table > tbody > tr');
    to replace:
    .children('td').children('table').children('tbody').children('tr'),
    don't use .find('td > table > tbody > tr'); in a table tree.
  • 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')
  • 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))");
  • tigris2
    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.
  • 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!
  • tigris2
    sorry, I didn't know, I just realized it...
  • So, $("ul").has("li") is faster than $("ul:has(li)") ?

    I suppose it is, compute two simple selectors is faster than one complex selector.
  • Is this distinct from .find() ? If so how?
  • 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.
  • $("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;
    }
    }
    });
    }
  • 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");
  • Oh Ok! I got the point now :)
    But I think the description should be updated.
  • Yeah, the description wasn't terribly clear. I've updated it. Hope that helps.