Verwenden Sie den Selektor 'beginnt mit' für einzelne Klassennamen


157

Wenn ich folgendes habe:

<div class="apple-monkey"></div>
<div class="apple-horse"></div>
<div class="cow-apple-brick"></div>

Ich kann den folgenden Selektor verwenden, um die ersten beiden DIVs zu finden:

$("div[class^='apple-']")

Wenn ich jedoch Folgendes habe:

<div class="some-other-class apple-monkey"></div>
<div class="apple-horse"></div>
<div class="cow-apple-brick"></div>

Es wird nur das zweite DIV gefunden, da die Klasse des ersten Divs als String zurückgegeben wird (glaube ich) und nicht mit 'apple-', sondern mit 'some-' beginnt.

Eine Möglichkeit, dies nicht zu umgehen, besteht darin, nicht mit zu beginnen, sondern Folgendes zu enthalten:

$("div[class*='apple-']")

Das Problem dabei ist, dass in meinem Beispiel auch der 3. DIV ausgewählt wird.

Frage: Wie können Sie über jQuery Prädikatselektoren für einzelne Klassennamen und nicht für das gesamte Klassenattribut als Zeichenfolge verwenden? Geht es nur darum, die KLASSE zu greifen, sie dann in ein Array aufzuteilen und dann jede einzelne mit Regex zu durchlaufen? Oder gibt es eine elegantere / weniger ausführliche Lösung?

Antworten:


303

Klassen, die mit "apple-" beginnen, plus Klassen, die "apple-" enthalten

$("div[class^='apple-'],div[class*=' apple-']")

5
+1. Obwohl ich dem Vorschlag von @parrots zustimme, dass "apple" hier eine eigene Klasse sein sollte, da es offensichtlich mehrere Divs überlappt, aber dennoch eine eigenständige Einheit ist. Dies löst jedoch das Problem.
Jvenema

Hmm ... klug! Ich hatte nicht daran gedacht, dort Platz zu nutzen. Kann man boolesche Operatoren in einem jquery-Selektor verwenden? Im Idealfall wäre das oben genannte "ODER", um den (seltenen und wahrscheinlich vermeidbaren) Fall zu vermeiden, in dem mehr als eine Klasse mit "Apfel-"
DA

Ich bin mir nicht sicher, ob ich das verstehe, aber wenn Sie den zweiten Selektor nur verwenden möchten, wenn der erste Selektor null Elemente zurückgibt, können Sie var divs = $("div[class^='apple-']"); if(divs.length == 0) divs = $("div[class*=' apple-']");
Josh Stodola

Jetzt, wo ich darüber nachdenke, funktioniert Ihre anfängliche Lösung einwandfrei. Ein DIV mit einer Klasse wie "Apfel-Ziegel-Apfel-Pferd" wird immer noch nur einmal im jQuery-Objekt ausgewählt.
DA.

Verwenden Sie * anstelle von div, wenn Sie die Klasse nicht für ein bestimmtes Element begrenzen :)
Hidayt Rahman

13

Ich würde empfehlen, "Apfel" zu einer eigenen Klasse zu machen. Sie sollten das Starten mit / enden mit vermeiden, wenn Sie können, da die Auswahl mit div.appleviel schneller wäre. Das ist die elegantere Lösung. Haben Sie keine Angst, Dinge in separate Klassen aufzuteilen, wenn dies die Aufgabe einfacher / schneller macht.


Wie denkst du, wäre es viel schneller? Es muss immer noch das gesamte DOM scannen und das Klassenattribut auswerten. Es wäre (bestenfalls) geringfügig schneller, da das Klassenattribut nicht mit einem Teilstring versehen werden müsste. Unerheblich.
Josh Stodola

2
componenthouse.com/article-19 : Wenn Sie im Abschnitt get by class nachsehen, ist die Verwendung der regulären Punktsyntax normalerweise ein gutes Stück schneller als die Behandlung der Klasse als Attribut. Fügen Sie die Teilstringsuche hinzu (und die zusätzliche Arbeit, die er leisten muss, um Elemente mit mehreren Klassennamen aufzuteilen), und dies führt zu einer anständigen Leistungsersparnis.
Papageien

1
Genau. Der Haken ist, dass wir IE6 immer noch stark unterstützen und keine zusammengesetzten Selektoren in CSS unterstützen: .class1.class2.class3 als solche. Wir verlassen uns auf längere Klassennamen, bei denen 'Parameter' durch Bindestriche geteilt werden.
DA.

6

Dies ist für das Präfix mit

$("div[class^='apple-']")

Dies ist für den Anfang mit, so dass Sie nicht das '-' Zeichen drin haben müssen

$("div[class|='apple']")

Eine Reihe weiterer cooler Varianten des jQuery-Selektors finden Sie hier https://api.jquery.com/category/selectors/


6

Während die beste Antwort hier eine Problemumgehung für den speziellen Fall des Fragestellers ist, suchen Sie nach einer Lösung für die tatsächliche Verwendung von "beginnt mit" für einzelne Klassennamen:

Sie können diesen benutzerdefinierten jQuery-Selektor verwenden, den ich als :acp()"A Class Prefix" bezeichne. Der Code befindet sich am Ende dieses Beitrags.

var test = $('div:acp("starting_text")');

Dadurch werden alle <div>Elemente ausgewählt, bei denen mindestens ein Klassenname mit der angegebenen Zeichenfolge beginnt (in diesem Beispiel "Starttext"), unabhängig davon, ob sich diese Klasse am Anfang oder an einer anderen Stelle in den Klassenattributzeichenfolgen befindet.

<div id="1" class="apple orange lemon" />
<div id="2" class="orange applelemon banana" />
<div id="3" class="orange lemon apple" />
<div id="4" class="lemon orangeapple" />
<div id="5" class="lemon orange" />

var startsWithapp = $('div:acp("app")');

Dies gibt die Elemente 1, 2 und 3 zurück, jedoch nicht 4 oder 5.

Hier ist die Deklaration für den :acpbenutzerdefinierten Selektor, die Sie überall platzieren können:

$(function(){
    $.expr[":"].acp = function(elem, index, m){
          var regString = '\\b' + m[3];
          var reg = new RegExp(regString, "g");
          return elem.className.match(reg);
    }
});

Ich habe dies gemacht, weil ich viel GreaseMonkey-Hacking von Websites mache, auf denen ich keine Backend-Kontrolle habe. Daher muss ich häufig Elemente mit Klassennamen finden, die dynamische Suffixe haben. Es war sehr nützlich.


2

Versuche dies:

$("div[class]").filter(function() {
    var classNames = this.className.split(/\s+/);
    for (var i=0; i<classNames.length; ++i) {
        if (classNames[i].substr(0, 6) === "apple-") {
            return true;
        }
    }
    return false;
})

2
<div class="apple-monkey"></div>
<div class="apple-horse"></div>
<div class="cow-apple-brick"></div>

in diesem Fall als Frage Josh Stodola Antwort ist richtig Klassen, die mit "Apfel-" beginnen plus Klassen, die "Apfel-" enthalten

$("div[class^='apple-'],div[class*=' apple-']")

aber wenn Element mehrere Klassen wie diese haben

<div class="some-class apple-monkey"></div>
<div class="some-class apple-horse"></div>
<div class="some-class cow-apple-brick"></div>

dann wird Josh Stodolas Lösung nicht funktionieren,
dafür muss man so etwas tun

$('.some-parent-class div').filter(function () {
  return this.className.match(/\bapple-/);// this is for start with
  //return this.className.match(/apple-/g);// this is for contain selector
}).css("color","red");

Vielleicht hilft es jemand anderem, danke


0

Wenn ein Element mehrere Klassen hat, funktioniert "[class ^ = 'apple-']" nicht, z

<div class="fruits apple-monkey"></div>

Das OP erwähnt dies in der Frage.
Gans
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.