Tuesday, April 17, 2012

JQuery "hasparent”


The JQuery "has" method effectively selects all elements where they have particular descendants.



I want to select elements based on the fact they have particular ancestors. I know about parent([selector]) and parents([selector]) but this selects the parents and not the children with the parents.



So is there an ancestor equivalent of "has"?



(note: I already have the context of an element further down the hierarchy and I will be selecting based on this so I can't do a "top down" query)



Update



I've obviously explained myself really badly here, so I'll try and clarify:




<ul class="x">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<ul class="y">
<li>4</li>
<li>5</li>
<li>6</li>
</ul>



I have a jquery object that already consists of elements 2,3,4 and 5. I want to select those elements who have a parent with the class = x.



Hope that makes more sense.


Source: Tips4all

7 comments:

  1. If you wanted to filter out items that don't have a particular parent, you can use $.filter():

    $(".element")
    .filter(function(){ return $(this).parents(".parent").length })
    .css("background-color", "red");​​​​​​​​​​​​​​​


    So of all .element items on the page, you will set the background-color to red for those which exist within a .parent element somewhere down the DOM.

    Original Answer

    If you wanted to select only .yumyum elements that have a parent of .parent:

    $(".parent .yumyum").css("background-color", "#CCC");




    <p class="parent">
    <span class="yumyum">Hello</span> <!-- has parent -->
    <span class="yumyum">Hello</span> <!-- has parent -->
    </p>
    <span class="yumyum">Hello</span> <!-- has not parent -->

    ReplyDelete
  2. If I understand your question correctly, this would do:

    $.fn.hasAncestor = function(a) {
    return this.filter(function() {
    return !!$(this).closest(a).length;
    });
    };

    $('.element').hasAncestor('.container').myAction();

    <div class="container">
    <span>
    <strong class="element">strong</strong>
    </span>
    </div>

    ReplyDelete
  3. if ( $('.foo').parents('.parentSelector').length ) { // has parent }

    ReplyDelete
  4. Try this

    ul.myList > li > a


    This selector selects only links that are direct children of list elements, which are
    in turn direct children of elements that have the class myList.

    ReplyDelete
  5. The easy way is this:

    // all children of a specific parent match
    $('parentSelector').children();

    // All children matching a specific pattern, one level deep
    $('parentSelector > childSelector');
    // or
    // $('parentSelector').children('childSelector');

    // All children matching a specific pattern, multiple levels deep
    $('parentSelector childSelector');
    // or
    // $('parentSelector').find('childSelector');


    or did you really need something more complicated than that?

    Edit: If you already have an element, you can combine this with the parent() command, like so:

    myElement.parents('parentSelector').find('childSelector'); // Will include self

    ReplyDelete
  6. Since you said are already targeting an element, couldn't you just use siblings()?

    $('li.selected').siblings().addClass('selected');


    or if you had to make sure a particular parent class existed, then try this:

    $('li.selected').parent('ul.x').children().addClass('selected');

    ReplyDelete
  7. object.each(function(){
    element = $(this);
    if(element.parent().hasClass("x")){
    //do stuff
    }
    });


    this will affect every item in your object that has parent .x

    ReplyDelete