I have
var $set = $('.foo,.bar').filter(
function() {return $(this).parents('.baz').length < 1;});
as a way to select all the elements whose classes are either foo
or bar
and who do not descend from an element whose class is baz
. Is there a selector that will accomplish the same thing without the need for a filtering lambda?
<div class='foo'/><!--match this-->
<div class='bar'/><!--match this-->
<div class='baz'>
<div class='foo'/> <!--don't match this-->
</div>
The truth of the matter is that jQuery simply does not have a particularly elegant way to do what you want. While chaos' answer does work, you have to wonder whether the complicated selector (that would be about as slow as a selector can be in a complicated webpage) is worth it over the more verbose but faster filter function you have. This is not really that big of a deal, I am just personally weary of particularly long, convoluted selectors when I can avoid it.
A different option is to create your own selector, since jQuery is awesome:
jQuery.expr[':'].parents = function(a,i,m){
return jQuery(a).parents(m[3]).length < 1;
};
$('.foo,.bar').filter(':parents(.baz)');
The expr
map is part of the Sizzle selector engine and documentation can be found here: Sizzle Custom Pseudo-Selectors
$('.foo:not(.baz .foo),.bar:not(.baz .bar)')
I couldn't get this to work:
$(".children:not(#parent .children)");
But I can get this to work:
$(".children").not($("#parent .children"));
Note: Not sure if this has something to do with the jQuery version I'm using 1.2.6
try this one:
$('div').filter(function () {
return ($(this).parent().not('.baz'));
})
The selector chaos gives should work:
$('.foo:not(.baz .foo),.bar:not(.baz .bar)')
Just wanted to give you a tip about an extension to FireBug called FireFinder that you can use to test your css/jquery selectors.
From the website: Firefinder is an extension to Firebug (in Firefox) and offers the functionality to, in a quick way, find HTML elements matching chosen CSS selector(s) or XPath expression. It allows you to instantly test your CSS selectors in the page while seeing the content at the same time, and matching elements will be highlighted.
var $li = jQuery('li', this).not('.dropdown-menu > li');
I'm using Roots theme and they change the dropdowns from 'sub-menu' to '.dropdown-menu'
Add a :not('.baz') to your top level selector.