views:

528

answers:

6
+1  Q: 

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.

A: 

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

psychotik
this would only really work for a single element. I want to select all the children with parents that match a certain criteria. But I've already got a jquery object to select from which is lower down the hierarchy (if this makes sense)
Chris Simpson
why will this only for a single element? If your selectors are correct, you should be fine. My code above reads "for _all_ elements with class 'foo', find their parents with class 'parentSelector' and return that jQuery collection". Maybe I'm missing something ... provide an example?
psychotik
you are saying "if my element has got a matching parent, do something". I want to say "based on this list of elements, give me a list of elements that have parents matching a particular criteria"
Chris Simpson
+5  A: 

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 -->
Jonathan Sampson
this is the "top down" approach I'm trying to avoid as I already have the element I want to start with. That's what I was trying to explain in my last note. Let's say you already have the second and third spans on that list in a jquery variable, how do you further filter that list?
Chris Simpson
If I understand you correctly, Chris, my perpended update addresses that.
Jonathan Sampson
I'm not too familiar with the filter method. based on my edit, do you still think this would do it?
Chris Simpson
@Chris Simpson: Judging from your edits (and Jonathan's), I'd have to say yes. Assuming you replace `.parent` with `.x` that is.
R. Bemrose
actually scratch that, it makes perfect sense. I'll give it a go
Chris Simpson
works a charm thanks
Chris Simpson
A: 

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');
fudgey
A: 

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
R. Bemrose
added example html to the question that may explain things a little better
Chris Simpson
A: 

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.

streetparade
+2  A: 

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>
David
+1 That's a good one
fudgey
yeah that's good
Chris Simpson