Używanie selektora „zaczyna się od” na nazwach poszczególnych klas

157

Jeśli mam:

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

Mogę użyć następującego selektora, aby znaleźć pierwsze dwa DIV:

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

Jeśli jednak mam to:

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

Znajdzie tylko drugą DIV, ponieważ klasa pierwszego div jest zwracana jako ciąg (tak mi się wydaje) i tak naprawdę nie zaczyna się od „apple-”, ale raczej „some-”

Jednym ze sposobów jest nieużywanie zaczyna się od, ale zamiast tego zawiera:

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

Problem w tym, że w moim przykładzie wybierze również 3 DIV.

Pytanie: Jaki jest właściwy sposób używania selektorów predykatów w nazwach poszczególnych klas, a nie całego atrybutu klasy jako łańcucha, za pośrednictwem jQuery? Czy to tylko kwestia przechwycenia CLASS, a następnie podzielenia jej na tablicę, a następnie zapętlenia każdej z nich za pomocą wyrażenia regularnego? A może istnieje bardziej eleganckie / mniej rozwlekłe rozwiązanie?

DA.
źródło

Odpowiedzi:

303

Klasy zaczynające się od „jabłko-” oraz klasy zawierające „jabłko-”

$("div[class^='apple-'],div[class*=' apple-']")
Josh Stodola
źródło
5
+1. Chociaż zgadzam się z sugestią @parrots, że „jabłko” powinno być tutaj własną klasą, ponieważ w oczywisty sposób nakłada się na wiele elementów div, ale jest odrębną jednostką. Ale to rozwiązuje problem.
jvenema
Hmm ... sprytnie! Nie myślałem o wykorzystaniu tam przestrzeni. Czy można używać operatorów logicznych w selektorze jQuery? Idealnie byłoby, gdyby powyższe było „LUB”, aby uniknąć (rzadkiego i prawdopodobnie możliwego do uniknięcia) przypadku, w którym istnieje więcej niż jedna klasa zaczynająca się od „jabłko-”
DA.
Nie jestem pewien, czy rozumiem, ale jeśli chcesz użyć drugiego selektora tylko wtedy, gdy pierwszy selektor zwraca zero elementów, możesz zrobić coś takiego: var divs = $("div[class^='apple-']"); if(divs.length == 0) divs = $("div[class*=' apple-']");
Josh Stodola
Teraz, kiedy o tym myślę, Twoje początkowe rozwiązanie działa dobrze. DIV, który miał klasę taką jak „jabłko-klocek jabłoni-konik” byłby nadal zaznaczony tylko raz w obiekcie jQuery.
DA.
użyj * zamiast div, jeśli nie ograniczasz klasy dla konkretnego elementu :)
Hidayt Rahman
13

Poleciłbym uczynić „jabłko” własną klasą. Jeśli możesz, powinieneś unikać rozpoczynania od / kończy się na, ponieważ możliwość wyboru za pomocą div.applebyłaby znacznie szybsza. To bardziej eleganckie rozwiązanie. Nie bój się dzielić rzeczy na osobne klasy, jeśli sprawia to, że zadanie jest prostsze / szybsze.

Papugi
źródło
Jak myślisz, że byłoby to dużo szybsze? Nadal musi skanować cały DOM i oceniać atrybut klasy. Byłby nieznacznie szybszy (w najlepszym przypadku), ponieważ nie musiałby tworzyć łańcucha atrybutu class. Nieistotny.
Josh Stodola
2
componenthouse.com/article-19 : Jeśli zajrzysz do sekcji get by class, użycie zwykłej składni z kropkami jest zwykle trochę szybsze niż traktowanie klasy jako atrybutu. Dodaj wyszukiwanie podłańcuchów (i dodatkową pracę, jaką będzie musiał wykonać, aby wyodrębnić elementy o wielu nazwach klas), a to da przyzwoite oszczędności wydajności.
Papugi
1
Zgadzam się. Problem polega na tym, że nadal mocno wspieramy IE6 i nie obsługuje on selektorów złożonych w CSS: .class1.class2.class3 jako taki, polegamy na używaniu dłuższych nazw klas, w których „parametry” są podzielone myślnikami.
DA.
6

to jest dla przedrostka z

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

to jest na początek, więc nie musisz mieć tam znaku '-'

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

możesz znaleźć kilka innych fajnych odmian selektora jQuery tutaj https://api.jquery.com/category/selectors/

Mexicoder
źródło
6

Chociaż najważniejszą odpowiedzią tutaj jest obejście konkretnego przypadku osoby pytającej, jeśli szukasz rozwiązania faktycznego używania słowa „zaczyna się od” w nazwach poszczególnych klas:

Możesz użyć tego niestandardowego selektora jQuery, który nazywam :acp()„prefiksem klasy A”. Kod znajduje się na dole tego posta.

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

Spowoduje to wybranie wszystkich <div>elementów, które mają co najmniej jedną nazwę klasy zaczynającą się od podanego ciągu (w tym przykładzie „tekst_początkowy”), niezależnie od tego, czy ta klasa znajduje się na początku, czy w innym miejscu w ciągach atrybutów klasy.

<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")');

To zwróci elementy 1, 2 i 3, ale nie 4 lub 5.

Oto deklaracja :acpselektora niestandardowego, którą możesz umieścić w dowolnym miejscu:

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

Zrobiłem to, ponieważ robię wiele hakowania GreaseMonkey na stronach internetowych, na których nie mam kontroli wewnętrznej, więc często muszę znaleźć elementy z nazwami klas, które mają dynamiczne sufiksy. To było bardzo przydatne.

equazcion
źródło
2

Spróbuj tego:

$("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;
})
Gumbo
źródło
2
<div class="apple-monkey"></div>
<div class="apple-horse"></div>
<div class="cow-apple-brick"></div>

w tym przypadku jako pytanie Josh Stodola odpowiedź jest poprawna Klasy zaczynające się od „jabłko-” plus klasy zawierające „jabłko-”

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

ale jeśli element ma wiele takich klas

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

wtedy rozwiązanie Josha Stodoli nie zadziała,
ponieważ trzeba zrobić coś takiego

$('.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");

może to pomaga komuś innemu dzięki

code.rider
źródło
0

Jeśli element ma klasy wielokrotności "[class ^ = 'apple-']" nie działa, np

<div class="fruits apple-monkey"></div>
Ramón Mtz
źródło
PO wspomina o tym w pytaniu.
Goose