Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jquery hasClass for multiple classes

I am having,

<tr valign="top">
    <th class="chkCol fixed">..checkbox..</th>
    <th class="fixed">..head..</th>
</tr>

Now in Jquery I am calling a function like,

if($(this).hasClass("fixed")){
   ....
}

If I call $(this).hasClass("fixed"), then I need to get only head not checkbox and that is working perfect in Jquery 1.4.2 but now I updated to jquery 1.6.1. Now I am getting checkbox inside if condition.

Please Help,

Thanks in advance

like image 458
Max Avatar asked Jun 08 '11 14:06

Max


2 Answers

I'd be very surprised if jQuery 1.4.2 gets this wrong jQuery 1.4.2 does not get this wrong. hasClass("fixed") should be true in both cases, in all versions of jQuery. Here's an example using v1.6.1, and the same example using v1.4.2. Both work fine.

If you want to check that "fixed" it's the only class on an element, that's more easily done without jQuery, by going directly to the reflected property:

if (this.className === "fixed") {
    // ...
}

className is a property reflecting the "class" attribute, and like the "class" attribute it's a space-delimited string.

The above will fail, of course, if the element has any other class on it as well, like "fixed something-else".

If you specifically want to check it has "fixed" and doesn't have "chkCol", then you have to do that on purpose:

var $this = $(this);
if ($this.hasClass("fixed") && !$this.hasClass("chkCol")) {
    // ...
}

If you were doing this in a selector (rather than checking an element you already had) you could use the selector ".fixed:not(.chkCol)". But although you can do that with an element you already have using is, it's unnecessarily expensive (jQuery has to parse the selector).


Update: You've said that you've tried the && !$this.hasClass("chkCol") thing and it hasn't worked. That means that something earlier in the if condition has already determined the outcome of the expression as a whole, and so the result of the !$this.hasClass("chkCol") part makes no difference (and isn't getting run at all, as JavaScript short-circuits expressions).

Example:

var x = 1;

if (x == 1 || $this.hasClass("fixed") && !$this.hasClass("chkCol"))

In that case, because x is 1, nothing to the right of the || is even looked at at all; the expression's value is already true.


Update 2:

You've said you're using hasClass, but in a comment on another answer you said:

If i use $(this).attr('class') == "fixed", then not at all going into if condition

I don't suppose what you're actually doing is this:

if ($(this).attr('className') == "fixed") {
    // ...
}

Note that's "className", not "class". If that's what you're doing, that will not work on 1.6.1 but it will on 1.4.2. There is no attribute called "className"; there's an attribute called "class" and a property called "className". jQuery 1.6.x differentiates between attributes and properties.

My code above, using hasClass, will work on all versions. Or change your code to use attr("class") rather than attr("className").

Here's a v1.4.2 example showing attr("className") working (which it shouldn't). Here's a v1.6.1 example showing attr("className") not working (which is correct). Both versions show the correct way to get at the "class" attribute.

like image 72
T.J. Crowder Avatar answered Oct 02 '22 01:10

T.J. Crowder


You could either do this:

if ($(this).attr('className') === 'fixed')

or else:

if ($(this).not('.chkCol').hasClass('fixed'))

I think it'd be better to make sure that "chkCol" elements never get the "fixed" class in the first place.

edit — the ever-perceptive @T. J. Crowder points out correctly that ".attr()" is, as of jQuery 1.6, the wrong way to get property values from elements. There's a degree of angelic pin dancing involved in the explanation of why that's the case, but suffice to say that you'd now use:

if ($(this).prop('className') === 'fixed')
like image 37
Pointy Avatar answered Oct 02 '22 01:10

Pointy