Existe-t-il un sélecteur jQuery: contient insensible à la casse?

145

Existe-t-il une version insensible à la casse du sélecteur : contains jQuery ou dois-je faire le travail manuellement en boucle sur tous les éléments et en comparant leur .text () à ma chaîne?

Tapoter
la source
2
Pour jQuery 8.1 + vérifiez cette réponse
Praveen
1
^ C'est 1.8.1, pas 8.1.
TylerH
Bon exemple ici .
劉鎮 瑲

Réponses:

125

Ce que j'ai fini par faire pour jQuery 1.2, c'est:

jQuery.extend(
    jQuery.expr[':'], { 
        Contains : "jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0" 
});

Cela étendra jquery pour avoir un sélecteur: Contains insensible à la casse, le sélecteur: contains reste inchangé.

Edit: Pour jQuery 1.3 (merci @ user95227) et plus tard, vous avez besoin

jQuery.expr[':'].Contains = function(a,i,m){
     return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0;
};

Edit: Apparemment accéder directement au DOM en utilisant

(a.textContent || a.innerText || "") 

au lieu de

jQuery(a).text()

Dans l'expression précédente, cela accélère considérablement, alors essayez à vos risques et périls si la vitesse est un problème. (voir la question de @John )

Dernière modification: pour jQuery 1.8, cela devrait être:

jQuery.expr[":"].Contains = jQuery.expr.createPseudo(function(arg) {
    return function( elem ) {
        return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
    };
});
Tapoter
la source
Je voulais juste faire savoir aux gens que la solution décrite par @Pat et d'autres pour jQuery 1.3 fonctionne également pour la 1.4.3.
Jim Ade
Lien vers la question / réponse de @ John depuis la suppression du lien ici: stackoverflow.com/questions/1407434/…
Mottie
Cela ne fonctionne pas pour jQuery 1.8. Voir la réponse de seagullJS ci-dessous pour une version mise à jour - stackoverflow.com/a/12113443/560114
Matt Browne
105

Pour le rendre éventuellement insensible à la casse: http://bugs.jquery.com/ticket/278

$.extend($.expr[':'], {
  'containsi': function(elem, i, match, array)
  {
    return (elem.textContent || elem.innerText || '').toLowerCase()
    .indexOf((match[3] || "").toLowerCase()) >= 0;
  }
});

puis utilisez à la :containsiplace de:contains

montréal
la source
3
l'ajout d'une nouvelle fonction est mieux que de m'écraser, j'utilise maintenant cette option (fonctionne comme un charme)
GôTô
22
cela devrait être ajouté à la bibliothèque standard jquery
user482594
41

Depuis jQuery 1.3, cette méthode est obsolète. Pour que cela fonctionne, il doit être défini comme une fonction:

jQuery.expr[':'].Contains = function(a,i,m){
    return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0;
};
utilisateur95227
la source
38

Si quelqu'un (comme moi) est intéressé, que signifient a et m [3] dans la définition Contains .


KEY / LEGEND: Paramètres rendus disponibles par jQuery pour une utilisation dans les définitions de sélecteur:

r = jQuery tableau d'éléments en cours d'examen. (par exemple: r.length = Nombre d'éléments)

i = index de l'élément actuellement examiné, dans le tableau r .

a = élément actuellement sous contrôle. L'instruction Selector doit retourner true pour l'inclure dans ses résultats correspondants.

m [2] = nodeName ou * que nous recherchons (à gauche de deux points).

m [3] = paramètre passé dans le: selector (param). Typiquement un numéro d'index, comme dans : nth-of-type (5) , ou une chaîne, comme dans : color (bleu) .

Alexandre Prokofyev
la source
31

Dans jQuery 1.8, vous devrez utiliser

jQuery.expr[":"].icontains = jQuery.expr.createPseudo(function (arg) {                                                                                                                                                                
    return function (elem) {                                                            
        return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;        
    };                                                                                  
});
mouetteJS
la source
2
A parfaitement fonctionné, merci! Juste mis à jour à 1.8 et cela a cessé de fonctionner.
Andreas
3
merci pour la mise à jour. Juste mis à jour vers JQuery 1.8 et il a cessé de fonctionner
Wasim
15

Une variante qui semble fonctionner légèrement plus rapidement et qui permet également les expressions régulières est:

jQuery.extend (
    jQuery.expr[':'].containsCI = function (a, i, m) {
        //-- faster than jQuery(a).text()
        var sText   = (a.textContent || a.innerText || "");     
        var zRegExp = new RegExp (m[3], 'i');
        return zRegExp.test (sText);
    }
);



Non seulement cela est insensible à la casse, mais il permet des recherches puissantes telles que:

  • $("p:containsCI('\\bup\\b')") (Correspond à «Up» ou «up», mais pas à «upper», «wakeup», etc.)
  • $("p:containsCI('(?:Red|Blue) state')") (Correspond à "état rouge" ou "état bleu", mais pas à "état haut", etc.)
  • $("p:containsCI('^\\s*Stocks?')") (Correspond à "stock" ou "stocks", mais uniquement au début du paragraphe (en ignorant les espaces au début).)
Brock Adams
la source
11

Peut-être en retard ... mais,

Je préférerais suivre cette voie ...

$.extend($.expr[":"], {
"MyCaseInsensitiveContains": function(elem, i, match, array) {
return (elem.textContent || elem.innerText || "").toLowerCase().indexOf((match[3] || "").toLowerCase()) >= 0;
}
});

De cette façon, vous ne falsifiez PAS le NATIVE '.contains' de jQuery ... Vous aurez peut-être besoin de celui par défaut plus tard ... s'il est falsifié, vous pourriez vous retrouver à stackOverFlow ...

ErickBest
la source
6
jQuery.expr[':'].contains = function(a,i,m){
    return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0;
};

Le code de mise à jour fonctionne très bien dans la version 1.3, mais "contient" doit être en minuscules sur la première lettre contrairement à l'exemple précédent.


la source
1
Je pense qu'il voulait une fonction distincte de sorte que les deux :containset :Containsserait à la fois le travail en même temps.
joshperry
"le sélecteur: contient reste inchangé."
Harry B le
4

Reportez-vous ci-dessous pour utiliser ": contient" pour rechercher du texte ignorant sa casse à partir d'un code HTML

 $.expr[":"].contains = $.expr.createPseudo(function(arg) {
            return function( elem ) {
                return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
            };
        });
        $("#searchTextBox").keypress(function() {
          if($("#searchTextBox").val().length > 0){
            $(".rows").css("display","none");
            var userSerarchField = $("#searchTextBox").val();
            $(".rows:contains('"+ userSerarchField +"')").css("display","block");
          } else {
            $(".rows").css("display","block");
          }              
        });

Vous pouvez également utiliser ce lien pour trouver le code ignorant la casse en fonction de votre version de jquery, Make jQuery: contains Case-Insensitive

Umesh Patil
la source
2

Une version plus rapide utilisant des expressions régulières.

$.expr[':'].icontains = function(el, i, m) { // checks for substring (case insensitive)
    var search = m[3];
    if (!search) return false;

    var pattern = new RegExp(search, 'i');
    return pattern.test($(el).text());
};
Rotaercz
la source
Excellent travail! Merci beaucoup. Je pense que c'est la meilleure et la plus récente réponse à cette question.
mavrosxristoforos le
0

J'ai eu un problème similaire avec ce qui suit ne fonctionne pas ...

// This doesn't catch flac or Flac
$('div.story span.Quality:not(:contains("FLAC"))').css("background-color", 'yellow');

Cela fonctionne et sans avoir besoin d'une extension

$('div.story span.Quality:not([data*="flac"])').css("background-color", 'yellow');

Cela fonctionne aussi, mais tombe probablement dans la catégorie "boucle manuelle" ....

$('div.story span.Quality').contents().filter(function()
{
  return !/flac/i.test(this.nodeValue);
}).parent().css("background-color", 'yellow');
shao.lo
la source
0

Nouvelle variable, je lui donne le nom de subString et je mets la chaîne que vous souhaitez rechercher dans certains éléments de texte. Ensuite, en utilisant le sélecteur Jquery, sélectionnez les éléments dont vous avez besoin comme mon exemple $("elementsYouNeed")et filtrez par .filter(). Dans le, .filter()il comparera chaque élément $("elementsYouNeed")avec la fonction.

Dans la fonction .toLowerCase()que j'utilise pour le texte de l'élément, aussi subString qui peut éviter la condition sensible à la casse et vérifier s'il y a une sous-chaîne dedans. Après cela, la .filter()méthode construit un nouvel objet jQuery à partir d'un sous-ensemble des éléments correspondants.

Vous pouvez maintenant obtenir les éléments de correspondance dans matchObjects et faire ce que vous voulez.

var subString ="string you want to match".toLowerCase();

var matchObjects = $("elementsYouNeed").filter(function () {return $(this).text().toLowerCase().indexOf(subString) > -1;});
劉鎮 瑲
la source