if ($(this).hasClass('white')) {console.log('white');};
equates to true and prints to the console. How do I test if it does not have the class white
on the $(this) selector? I have
if ($('this:not(.white)')) {console.log('not white');};
and
if ($(this).not('.white')) {console.log('not white');};
and
several other combinations?
I know I likely should use the .not() method, and can't figure out how to use the :not selector in combination with the $(this)
selector.
I would like that when the element is clicked, that I can see one true and one false statement. (it either does or doesn't have the class 'white')
You can use not logical operator
, Try this:
if (!$(this).hasClass('white')) {console.log('not white');};
Returns false if its single operand can be converted to true; otherwise, returns true.
I think it might be helpful for you to understand the domains you're crossing in those two statements.
if ($('this:not(.white)')) {console.log('not white');};
This statement will not work, because the selector - this:not(.white)
will look for elements of this variety: <this class="white"></this>
. Your selector, in other words, is looking for an HTML element of type this
, which is not of class white
.
if ($(this).not('.white')) {console.log('not white');};
In this case, you are using $(this)
, which wraps the JavaScript object which the this
keyword refers to in a jQuery object, thus allowing you to utilize jQuery methods against that DOM element.
In order to get the effect that you're looking for, you have to understand that any STRING selector you pass to a $(selector)
is constrained to selectors which CSS can match. Thus - you can't use your "this" keyword that way.
What you can do, to check your effect, however, is the following:
if ($(this).is(':not(.white)')) {
console.log('Not White! :(');
} else {
console.log('White! :D');
}
Because you put this
inside the $()
block, the result is that any further jQuery chained methods which are applied are resolved against the DOM element to which this
refers in your current context. You are then checking the class using the CSS :not()
selector.
Please note, however, that the limitation of this approach is that if for whatever reason this
refers to multiple DOM elements, the .is()
result will only return true
if ALL such elements match the selector. So - consider this example:
<div class="one white element"></div>
<div class="one black element"></div>
<div class="one green element"></div>
$('.one.element').bind('click', function () {
// In this context, 'this' refers to the element which was clicked.
console.log( $(this).is(':not(.white)') );
// If you click either the black or green element, you will get a 'true',
// because those elements are not .white.
// If you click the white element, you will get a 'false',
// because that element does have the .white class
});
The problem is that the context for this
changes fairly often in most JavaScript applications, and therefore most programmers I know avoid using it whenever possible. Safer than the above is:
$('.one.element').bind('click', function (ev) {
var $el = $(ev.target);
console.log( $el.is(':not(.white)') );
// In this case, you avoid 'this' entirely, and target the actual element
// from which the event originated.
});
In this case, however, you run into the problem of nested items raising incorrect targets. Consider this case:
<div class="parent">
<div class="child">
text
</div>
</div>
$('.parent').bind('click', function (ev) {
var $el = $(ev.target);
console.log( $el.attr('class') );
});
In this case, if you click the parent
itself, you will get parent
as the result. If you click the child, however, even though the event is bound to the parent element, you will get child
because of event bubbling. The actual event was raised by the child element, and therefore you have mis-targeted.
So - usually when you are building plugins, it is wise to carefully control your references.
Example
<div class="parent">
<div class="child">
text
</div>
</div>
var $parent = $('.parent').bind('click', function () {
console.log( $parent.attr('class') );
});
Now it doesn't matter whether you click the parent or child, you get the correct result, and you know what you're referencing. No confusion of this
contextual changes and no chance of using the attributes of a subordinate node.
Incidentally - any of the methods posted in other answers here are valid, also.
// The following will all tell you if the node HAS the class:
$(selector).hasClass('white')
$(selector).is('.white')
$(selector).is('[class*=white]')
// The following will all tell you if the node DOES NOT have the class:
!$(selector).hasClass('white')
$(selector).not('.white')
$(selector).is(':not(.white)')
And - there are other ways to do it, but any of these should work for your purposes. :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With