4

Given HTML code like so -

<div id="parent" class="foo">
  <div id="child">
  </div>
</div>

How can I write a test to see if the child element has the class foo applied? I tried:

element
.children("#child") //successfully selects child
.hasClass("foo");   //false :(
John Slegers
  • 45,213
  • 22
  • 199
  • 169
David says Reinstate Monica
  • 19,209
  • 22
  • 79
  • 122

6 Answers6

0

That's probably because your #child does not have a foo class. The parent has it, right?!

PS. David, seems like you had enough for today :)

Uzbekjon
  • 11,655
  • 3
  • 37
  • 54
0

CSS classes don't work that way. They only apply to the element on which they are applied and should not affect the children explicitly like that.

karina
  • 805
  • 5
  • 10
  • Thats not exactly true though, is it? Specifically, in my example if the parent has an `ng-hide`, then the child is also hidden. – David says Reinstate Monica May 03 '16 at 20:58
  • @DavidGrinberg Well as i understand it, that is calculated after the fact. so the child class doesn't explicitly have that class. and so .hasClass will fail – karina May 03 '16 at 21:06
  • @DavidGrinberg Kinda! Classes aren't inherited, but some attributes applied by them are, like `color`. ng-hide applies `display:none` which is a bit of a special case - since the parent's box isn't present anymore, the children can't really be there either. But for example if you had a class that applied the `border` property, its children wouldn't inherit the border. – Dmiters May 03 '16 at 21:11
0

CSS classes don't trickle down like that, but you can still check if an ancestor has the class like this:

Check if any ancestor has a class using jQuery

Dmiters
  • 2,011
  • 3
  • 23
  • 31
0

Neither CSS or jQuery can do that. One suggestion is using closest.

$(function(){
  var element = $('#parent').children('#child');
  if (element.closest('.foo').length > 0) {
    //you will get true for .foo, #child, or #parent, or div, ...
    console.log('Yay!');
  } else {
    console.log('Duh!');
  }
});

Prints 'Yay!'.

That method will check if the element or an ancestor have the class you need. You can ask for a class or for an ID. If you want to check for hidden -as you said- elements, you can try the :hidden pseudoselector in the regular is call, rather than hasClass (Fiddle Here):

<div id="parent" class="foo" style='display: none'>
  <div id="child">
  </div>
</div>

$(function(){
  var element = $('#parent').children('#child');
  if (element.is(':hidden')) {
    console.log('Yay!');
  } else {
    console.log('Duh!');
  }
});

Prints 'Yay!'.

Another one is this, given your current DOM (Fiddle Here):

$(function(){
  var element = $('#parent').children('#child');
  if (element.is('.foo *')) {
    console.log('Yay!');
  } else {
    console.log('Duh!');
  }
});

Prints 'Yay!'.

However you're using ng-hide, which usually means AngularJS. Don't know what is your intention but if you are not creating a custom directive please avoid using jquery and rethink your problem.

Luis Masuelli
  • 12,079
  • 10
  • 49
  • 87
0

With jQuery

How to check with jQuery if any ancestor of an element has a class named foo :

$element.parents('.foo').length > 0

Demo

var $element = $('#child');

alert(
    $element.parents('.foo').length > 0
);

alert(
    $element.parents('.bar').length > 0
);
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<div id="parent" class="foo">
    <div id="child">
    </div>
</div>

(see also this Fiddle)


Without jQuery

How to check without jQuery if any ancestor of an element has a class named foo :

element.matches('.foo ' + element.tagName)

Demo

var element = document.getElementById('child');

alert(
    element.matches('.foo ' + element.tagName)
);

alert(
    element.matches('.bar ' + element.tagName)
);
<div id="parent" class="foo">
    <div id="child">
    </div>
</div>

(see also this Fiddle)

John Slegers
  • 45,213
  • 22
  • 199
  • 169
0

When you use .children() the selector has moved on to another DOM node. To traverse back to the parent you can just use .end(), i.e.:

element
.children("#child")//successfully selects child
.end()//moves cursor back the parent element
.hasClass("foo");//true :)
Terry
  • 63,248
  • 15
  • 96
  • 118