When used with the child selector >
, the two variants of jQuery\'s \"has\" behave differently.
Take this HTML:
This happens because the sizzle selector is looking at all Div's that have span children in the :has example. But in the .has example, it's passing all DIV's to the .has(), which then looks for something that shouldn't be a stand-alone selection. ("Has children of nothing").
Basically, :has() is part of the selection, but .has() gets passed those divs and then re-selects from them.
Ideally, you don't use selectors like this. The > being in the selector is probably a bug, as it's semantically awkward. Note: the child operator isn't meant to be stand-alone.
I'm always talking about v1.4.2 of jquery development release.
Description: Reduce the set of matched elements to those that have a descendant that matches the selector or DOM element.
Code:
var targets = jQuery( target );
return this.filter(function() {
for ( var i = 0, l = targets.length; i < l; i++ ) {
if ( jQuery.contains( this, targets[i] ) ) { //Calls line 3642
return true;
}
}
});
Line 3642 relates to a 2008 plugin compareDocumentPosition, but the important bit here is that we're now basically just running two jquery queries here, where the first one selects $("DIV")
and the next one selects $(">span")
(which returns null), then we check for children.
Description: Selects elements which contain at least one element that matches the specified selector.
Code:
return !!Sizzle( match[3], elem ).length;
They are two differnt tools, the :has uses sizzle 100%, and .has uses targets passed to it.
Note: if you think this is a bug, go fill out the bug ticket.