Czy istnieje jQuery: zawiera selektor niewrażliwy na wielkość liter?

145

Czy istnieje wersja selektora : zawiera jQuery bez rozróżniania wielkości liter , czy też powinienem wykonać tę pracę ręcznie, zapętlając wszystkie elementy i porównując ich .text () z moim ciągiem?

Poklepać
źródło
2
W przypadku jQuery 8.1 + sprawdź tę odpowiedź
Praveen
1
^ To jest 1.8.1, a nie 8.1.
TylerH
Dobry przykład tutaj .
劉鎮 瑲

Odpowiedzi:

125

To, co ostatecznie zrobiłem dla jQuery 1.2, to:

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

Spowoduje to rozszerzenie jquery tak, aby zawierał selektor: Zawiera selektor niewrażliwy na wielkość liter, selektor: zawiera niezmieniony.

Edycja: dla jQuery 1.3 (dzięki @ user95227) i później potrzebujesz

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

Edycja: najwyraźniej uzyskuje się bezpośredni dostęp do DOM za pomocą

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

zamiast

jQuery(a).text()

W poprzednim wyrażeniu znacznie go przyspiesza, więc jeśli problemem jest szybkość, spróbuj na własne ryzyko. (patrz @John „s pytanie )

Ostatnia edycja: dla jQuery 1.8 powinno to być:

jQuery.expr[":"].Contains = jQuery.expr.createPseudo(function(arg) {
    return function( elem ) {
        return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
    };
});
Poklepać
źródło
Chciałem tylko poinformować ludzi, że rozwiązanie opisane przez @Pat i innych dla jQuery 1.3 działa również dla 1.4.3.
Jim Ade
Link do pytania / odpowiedzi
@Johna,
To nie działa dla jQuery 1.8. Zobacz odpowiedź seagullJS poniżej, aby uzyskać zaktualizowaną wersję - stackoverflow.com/a/12113443/560114
Matt Browne
105

Aby opcjonalnie nie rozróżniać wielkości liter: 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;
  }
});

następnie użyj :containsizamiast:contains

montrealmike
źródło
3
dodanie nowej funkcji jest
lepsze
22
powinno to zostać dodane do standardowej biblioteki jquery
user482594,
41

Od wersji jQuery 1.3 ta metoda jest przestarzała. Aby to zadziałało, musi być zdefiniowane jako funkcja:

jQuery.expr[':'].Contains = function(a,i,m){
    return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0;
};
user95227
źródło
38

Jeśli ktoś (taki jak ja) jest zainteresowany, co oznaczają a i m [3] w definicji Zawiera .


KLUCZ / LEGENDA: Parametry udostępnione przez jQuery do użycia w definicjach selektorów:

r = jQuery tablica badanych elementów. (np .: r.length = liczba elementów)

i = indeks aktualnie badanego elementu w tablicy r .

a = element obecnie analizowany. Instrukcja selektora musi zwracać wartość true, aby uwzględnić ją w dopasowanych wynikach.

m [2] = nodeName lub *, którego szukamy (po lewej od dwukropka).

m [3] = parametr przekazany do: selector (param). Zazwyczaj numer indeksu, jak w : nth-of-type (5) , lub ciąg znaków, jak w : color (blue) .

Alexander Prokofyev
źródło
31

W jQuery 1.8 będziesz musiał użyć

jQuery.expr[":"].icontains = jQuery.expr.createPseudo(function (arg) {                                                                                                                                                                
    return function (elem) {                                                            
        return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;        
    };                                                                                  
});
seagullJS
źródło
2
Działało idealnie, dzięki! Właśnie zaktualizowano do wersji 1.8 i to przestało działać.
Andreas
3
dzięki za aktualizację. Właśnie zaktualizowano do JQuery 1.8 i przestało działać
Wasim
15

Odmiana, która wydaje się działać nieco szybciej i która pozwala również na wyrażenia regularne, to:

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



Nie tylko nie jest rozróżniana wielkość liter, ale także umożliwia zaawansowane wyszukiwanie, takie jak:

  • $("p:containsCI('\\bup\\b')") (Dopasowuje „Up” lub „up”, ale nie „Upper”, „Wakeup” itp.)
  • $("p:containsCI('(?:Red|Blue) state')") (Dopasowuje „stan czerwony” lub „stan niebieski”, ale nie „stan włączenia” itp.)
  • $("p:containsCI('^\\s*Stocks?')") (Dopasowuje „stock” lub „stocks”, ale tylko na początku akapitu (ignorując początkowe białe spacje).
Brock Adams
źródło
11

Może się spóźnić ... ale

Wolałbym iść tą drogą ...

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

W ten sposób NIE modyfikujesz NATIVE '.contains' jQuery ... Domyślny może być potrzebny później ... jeśli ktoś się przy nim manipuluje , możesz wrócić do stackOverFlow ...

ErickBest
źródło
6
jQuery.expr[':'].contains = function(a,i,m){
    return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0;
};

Kod aktualizacji działa świetnie w wersji 1.3, ale słowo „zawiera” powinno być zapisane małą literą na pierwszej literze, w przeciwieństwie do poprzedniego przykładu.


źródło
1
Myślę, że chciał mieć odrębną funkcję, aby obie :containsi :Containsdziałały jednocześnie.
joshperry
„selektor: zawiera pozostaje niezmieniony”.
Harry B
4

Zobacz poniżej, aby użyć „: zawiera”, aby znaleźć tekst ignorujący wielkość liter w kodzie 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");
          }              
        });

Możesz również użyć tego linku, aby znaleźć kod ignorujący wielkość liter na podstawie Twojej wersji jquery, Make jQuery: zawiera bez rozróżniania wielkości liter

Umesh Patil
źródło
2

Szybsza wersja korzystająca z wyrażeń regularnych.

$.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
źródło
Świetna robota! Dziękuję Ci bardzo. Uważam, że to najlepsza i najbardziej aktualna odpowiedź na to pytanie.
mavrosxristoforos
0

Miałem podobny problem z niedziałającymi następującymi ...

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

Działa to bez konieczności przedłużania

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

To też działa, ale prawdopodobnie należy do kategorii „ręczne zapętlanie” ....

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

Nowa zmienna Nadaję jej nazwę subString i wstawiam ciąg, który chcesz wyszukać w tekście niektórych elementów. Następnie za pomocą selektora Jquery wybierz potrzebne elementy, takie jak mój przykład, $("elementsYouNeed")i filtruj według .filter(). W .filter()będzie porównać każdy element $("elementsYouNeed")z funkcją.

W funkcji używam również .toLowerCase()dla elementu tekstowego subString, który może uniknąć warunku uwzględniającego wielkość liter i sprawdzić, czy jest w nim podstring. Następnie .filter()metoda konstruuje nowy obiekt jQuery z podzbioru pasujących elementów.

Teraz możesz pobrać elementy dopasowania w matchObjects i robić, co chcesz.

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

var matchObjects = $("elementsYouNeed").filter(function () {return $(this).text().toLowerCase().indexOf(subString) > -1;});
劉鎮 瑲
źródło