Welcher JQuery-Selektor schließt Elemente mit einem übergeordneten Element aus, das einem bestimmten Selektor entspricht?


72

ich habe

var $set = $('.foo,.bar').filter(
    function() {return $(this).parents('.baz').length < 1;});

um alle Elemente auszuwählen, deren Klassen entweder foooder sind barund die nicht von einem Element abstammen, dessen Klasse ist baz. Gibt es einen Selektor, der dasselbe erreicht, ohne dass ein Filter-Lambda erforderlich ist?

<div class='foo'/><!--match this-->
<div class='bar'/><!--match this-->
<div class='baz'>
    <div class='foo'/> <!--don't match this-->
</div>

2
Sie können die closestMethode verwenden, anstatt parentssie schneller zu machen. closesthört auf zu suchen, sobald ein übereinstimmendes Element gefunden wurde, während parentsder DOM-Baum zum Stammelement des Dokuments hochgerechnet wird, um übereinstimmende Elemente zu finden.
RayOnAir

Antworten:


79

Die Wahrheit ist, dass jQuery einfach keine besonders elegante Möglichkeit hat, das zu tun, was Sie wollen. Während die Antwort von Chaos funktioniert, müssen Sie sich fragen, ob sich der komplizierte Selektor (der ungefähr so ​​langsam wäre wie ein Selektor auf einer komplizierten Webseite) für die ausführlichere, aber schnellere Filterfunktion lohnt. Das ist nicht wirklich eine große Sache, ich persönlich bin es besonders leid, besonders lange, verschlungene Selektoren zu haben, wenn ich es vermeiden kann.

Eine andere Möglichkeit besteht darin, einen eigenen Selektor zu erstellen, da jQuery fantastisch ist:

jQuery.expr[':'].parents = function(a,i,m){
    return jQuery(a).parents(m[3]).length < 1;
};

$('.foo,.bar').filter(':parents(.baz)');

Die exprKarte ist Teil der Sizzle Selector Engine. Die Dokumentation finden Sie hier: Sizzle Custom Pseudo-Selectors


Akzeptieren, weil es vollständiger ist als Chaos. Wo finde ich die Dokumentation zur API für das expr-Array?
Dan Davies Brackett

Soweit ich weiß, gibt es eigentlich keine.
Paolo Bergantino

10
Das ist ordentlich, obwohl ich denke, ich könnte den Ausdrucksnamen in noparents ändern, da dies beschreibt, was es ein bisschen besser macht.
Matt Sach

Der Link zu dieser JSBin stimmt nicht mit der Antwort überein. Es ist eine Weile her, also muss die URL recycelt worden sein.
Gfullam

Ich habe einen Verweis auf die Dokumentation exprzu dieser Antwort hinzugefügt .
Matpie

31
$('.foo:not(.baz .foo),.bar:not(.baz .bar)')

18

Ich konnte das nicht zum Laufen bringen:

$(".children:not(#parent .children)");

Aber ich kann das zum Laufen bringen:

$(".children").not($("#parent .children"));

Hinweis: Ich bin mir nicht sicher, ob dies etwas mit der von mir verwendeten jQuery-Version 1.2.6 zu tun hat


Verwenden $().not()ist die einfachste Lösung. Und ist gut dokumentiert , um genau das zu tun, was gefragt wurde.
Peter


1

Das Selektor- Chaos sollte funktionieren:

$('.foo:not(.baz .foo),.bar:not(.baz .bar)')

Ich wollte Ihnen nur einen Tipp zu einer Erweiterung von FireBug namens FireFinder geben , mit der Sie Ihre CSS- / JQuery-Selektoren testen können.

Von der Website: Firefinder ist eine Erweiterung von Firebug (in Firefox) und bietet die Funktionalität, auf schnelle Weise HTML-Elemente zu finden, die mit ausgewählten CSS-Selektoren oder XPath-Ausdrücken übereinstimmen. Sie können Ihre CSS-Selektoren auf der Seite sofort testen und gleichzeitig den Inhalt anzeigen. Übereinstimmende Elemente werden hervorgehoben.


1

var $li = jQuery('li', this).not('.dropdown-menu > li');

Ich verwende das Roots-Thema und sie ändern die Dropdowns von "Untermenü" in ".dropdown-Menü".


0

Fügen Sie Ihrem Selektor der obersten Ebene ein: not ('. Baz') hinzu.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.