Utilisation du sélecteur «commence par» sur les noms de classe individuels

158

Si j'ai ce qui suit:

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

Je peux utiliser le sélecteur suivant pour trouver les deux premiers DIV:

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

Cependant, si j'ai ceci:

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

Il ne trouvera que le deuxième DIV, car la classe du premier div est retournée sous forme de chaîne (je pense) et ne commence pas réellement par 'apple-' mais plutôt par 'some-'

Une solution consiste à ne pas utiliser commence par, mais contient à la place:

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

Le problème avec cela est qu'il sélectionnera également le 3e DIV dans mon exemple.

Question: Via jQuery, quelle est la bonne façon d'utiliser les sélecteurs de prédicat sur les noms de classe individuels, plutôt que l'attribut de classe entier sous forme de chaîne? Est-ce juste une question de saisir la CLASSE, puis de la diviser en un tableau, puis de faire une boucle sur chaque individu avec regex? Ou existe-t-il une solution plus élégante / moins verbeuse?

DA.
la source

Réponses:

304

Classes commençant par "pomme-" plus les classes contenant "pomme-"

$("div[class^='apple-'],div[class*=' apple-']")
Josh Stodola
la source
5
+1. Bien que je sois d'accord avec la suggestion de @parrots selon laquelle "apple" devrait être sa propre classe ici, car il chevauche évidemment plusieurs divs mais est une entité distincte. Mais cela résout le problème.
jvenema
Hmm ... intelligent! Je n'avais pas pensé à utiliser l'espace là-dedans. Peut-on utiliser des opérateurs booléens dans un sélecteur jquery? Idéalement, ce qui précède serait «OU» pour éviter le cas (rare et probablement évitable) où il y a plus d'une classe regardant avec «pomme-»
DA.
Je ne suis pas sûr de comprendre, mais si vous souhaitez utiliser le deuxième sélecteur uniquement lorsque le premier sélecteur renvoie zéro élément, vous pouvez faire quelque chose comme ceci: var divs = $("div[class^='apple-']"); if(divs.length == 0) divs = $("div[class*=' apple-']");
Josh Stodola
maintenant que j'y pense, votre solution initiale fonctionne très bien. Un DIV qui avait une classe comme "apple-brick apple-horse" serait toujours sélectionné une seule fois dans l'objet jQuery.
DA.
utilisez * au lieu de div si vous ne limitez pas de classe pour un élément spécifique :)
Hidayt Rahman
13

Je recommanderais de faire de la "pomme" sa propre classe. Vous devriez éviter le début par / se terminant par si vous le pouvez, car pouvoir sélectionner en utilisant div.appleserait beaucoup plus rapide. C'est la solution la plus élégante. N'ayez pas peur de diviser les choses en classes séparées si cela rend la tâche plus simple / plus rapide.

Perroquets
la source
Comment pensez-vous que ce serait beaucoup plus rapide? Il doit encore analyser tout le DOM et évaluer l'attribut de classe. Ce serait légèrement plus rapide (au mieux) car il n'aurait pas à sous-chaîne l'attribut class. Négligeable.
Josh Stodola le
2
componenthouse.com/article-19 : Si vous regardez dans la section get by class, utiliser la syntaxe de point régulière est généralement un peu plus rapide que de traiter la classe comme un attribut. Ajoutez la recherche de sous-chaînes (et le travail supplémentaire qu'il devra faire pour séparer les éléments avec plusieurs noms de classe) et cela se traduira par des économies de performances décentes.
Perroquets
1
Je suis d'accord. Le hic, c'est que nous soutenons toujours fortement IE6 et qu'il ne prend pas en charge les sélecteurs composés dans CSS: .class1.class2.class3 en tant que tel, nous comptons sur l'utilisation de noms de classe plus longs où les `` paramètres '' sont divisés par des tirets.
DA.
6

c'est pour le préfixe avec

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

c'est pour commencer par donc vous n'avez pas besoin d'avoir le caractère '-' là-dedans

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

vous pouvez trouver un tas d'autres variations intéressantes du sélecteur jQuery ici https://api.jquery.com/category/selectors/

Mexicoder
la source
6

Bien que la réponse principale ici soit une solution de contournement pour le cas particulier du demandeur, si vous recherchez une solution pour utiliser réellement `` commence par '' sur les noms de classe individuels:

Vous pouvez utiliser ce sélecteur jQuery personnalisé, que j'appelle :acp()«Préfixe de classe A». Le code est au bas de cet article.

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

Cela sélectionnera tous les <div>éléments qui ont au moins un nom de classe commençant par la chaîne donnée ("starting_text" dans cet exemple), indépendamment du fait que cette classe soit au début ou ailleurs dans les chaînes d'attributs de classe.

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

Cela renverra les éléments 1, 2 et 3, mais pas 4 ou 5.

Voici la déclaration du :acpsélecteur personnalisé, que vous pouvez placer n'importe où:

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

J'ai fait cela parce que je fais beaucoup de piratage GreaseMonkey de sites Web sur lesquels je n'ai pas de contrôle backend, donc j'ai souvent besoin de trouver des éléments avec des noms de classes qui ont des suffixes dynamiques. Cela a été très utile.

equazcion
la source
2

Essaye ça:

$("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;
})
Gombo
la source
2
<div class="apple-monkey"></div>
<div class="apple-horse"></div>
<div class="cow-apple-brick"></div>

dans ce cas, la réponse de Josh Stodola est correcte Classes qui commencent par "apple-" plus les classes qui contiennent "apple-"

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

mais si l'élément a plusieurs classes comme celle-ci

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

alors la solution de Josh Stodola ne fonctionnera pas
car cela doit faire quelque chose comme ça

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

peut-être que cela aide quelqu'un d'autre merci

code.rider
la source
0

Si un élément a plusieurs classes "[class ^ = 'apple-']" ne fonctionne pas, par exemple

<div class="fruits apple-monkey"></div>
Ramón Mtz
la source
Le PO le mentionne dans la question.
Goose