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


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;
    };
});

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


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;
};

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) .


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;        
    };                                                                                  
});

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).)

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 ...


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.


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


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());
};

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

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;});
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.