Existe um jQuery que não diferencia maiúsculas de minúsculas: contém seletor?

145

Existe uma versão que não diferencia maiúsculas de minúsculas do seletor : contém jQuery ou devo fazer o trabalho manualmente fazendo um loop sobre todos os elementos e comparando seu .text () à minha string?

Pat
fonte
2
Para jQuery 8.1 + verifique esta resposta
Praveen
1
^ Isso é 1.8.1, não 8.1.
TylerH
Bom exemplo aqui .
瑲 瑲 14/01

Respostas:

125

O que acabei fazendo no jQuery 1.2 é:

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

Isso estenderá o jquery para ter um: Contém seletor que não diferencia maiúsculas de minúsculas, o seletor: contém permanece inalterado.

Edit: Para jQuery 1.3 (obrigado @ user95227) e mais tarde você precisa

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

Editar: aparentemente acessando o DOM diretamente usando

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

ao invés de

jQuery(a).text()

Na expressão anterior, acelera consideravelmente; portanto, tente por sua conta e risco se a velocidade é um problema. (veja a pergunta de @John )

Última edição: Para o jQuery 1.8, deve ser:

jQuery.expr[":"].Contains = jQuery.expr.createPseudo(function(arg) {
    return function( elem ) {
        return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
    };
});
Pat
fonte
Só queria que as pessoas soubessem que a solução descrita pelo @Pat e outros para o jQuery 1.3 também funciona para a 1.4.3.
Jim Ade
Link para a pergunta / resposta de @ John desde que o link aqui foi excluído: stackoverflow.com/questions/1407434/…
Mottie
Isso não funciona para o jQuery 1.8. Veja a resposta da seagullJS abaixo para obter uma versão atualizada - stackoverflow.com/a/12113443/560114
Matt Browne
105

Para torná-lo opcionalmente sem distinção entre maiúsculas e minúsculas: 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;
  }
});

então use em :containsivez de:contains

montrealmike
fonte
3
adicionando uma nova função é melhor do que o de substituição para mim, eu agora usar esta opção (funciona como um encanto)
Goto
22
isso deve ser adicionado à biblioteca jquery padrão
user482594
41

A partir do jQuery 1.3, esse método está obsoleto. Para que isso funcione, ele precisa ser definido como uma função:

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

Se alguém (como eu) está interessado, o que a e m [3] significam em Contém a definição.


CHAVE / LEGENDA: Parâmetros disponibilizados pelo jQuery para uso nas definições do seletor:

r = matriz jQuery de elementos sendo examinados. (por exemplo: r.length = Número de elementos)

i = índice do elemento atualmente em análise, na matriz r .

a = elemento atualmente em análise. A instrução seletor deve retornar true para incluí-la em seus resultados correspondentes.

m [2] = nodeName ou * que estamos procurando (à esquerda de dois pontos).

m [3] = param passado no seletor: (param). Normalmente, um número de índice, como em : enésimo tipo (5) , ou uma sequência de caracteres, como em : cor (azul) .

Alexander Prokofyev
fonte
31

No jQuery 1.8, você precisará usar

jQuery.expr[":"].icontains = jQuery.expr.createPseudo(function (arg) {                                                                                                                                                                
    return function (elem) {                                                            
        return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;        
    };                                                                                  
});
gaivotaJS
fonte
2
Funcionou perfeitamente, obrigado! Acabei de atualizar para 1.8 e isso parou de funcionar.
Andreas
3
thanx pela atualização. Apenas atualizado para JQuery 1,8 e ele parou de funcionar
Wasim
15

Uma variação que parece ter um desempenho um pouco mais rápido e que também permite expressões regulares é:

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



Isso não diferencia apenas maiúsculas de minúsculas, mas permite pesquisas poderosas como:

  • $("p:containsCI('\\bup\\b')") (Corresponde a "Up" ou "up", mas não "upper", "wakeup" etc.)
  • $("p:containsCI('(?:Red|Blue) state')") (Corresponde a "estado vermelho" ou "estado azul", mas não a "estado ativo" etc.)
  • $("p:containsCI('^\\s*Stocks?')") (Corresponde a "material" ou "material", mas apenas no início do parágrafo (ignorando qualquer espaço em branco à esquerda).)
Brock Adams
fonte
11

Pode se atrasar ... mas,

Eu preferiria ir por esse caminho ..

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

Dessa forma, você NÃO adulterará o NATIVE '.contains' do jQuery ... Você pode precisar do padrão mais tarde ... se adulterado, poderá voltar ao stackOverFlow ...

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

O código de atualização funciona muito bem na versão 1.3, mas "contém" deve estar em minúsculas na primeira letra, diferente do exemplo anterior.


fonte
1
Eu acho que ele queria uma função distinta para que ambos :containse :Containstrabalhassem simultaneamente.
Joshperry
"o seletor: contém permanece inalterado."
Harry B
4

Consulte abaixo para usar ": contains" para encontrar o texto ignorando a distinção entre maiúsculas e minúsculas de um código 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");
          }              
        });

Você também pode usar este link para localizar o código de ignição de maiúsculas e minúsculas com base na sua versão jquery, Make jQuery: contém maiúsculas e minúsculas

Umesh Patil
fonte
2

Uma versão mais rápida usando expressões regulares.

$.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
fonte
Excelente trabalho! Muito obrigado. Acredito que esta é a melhor e mais atualizada resposta a essa pergunta.
mavrosxristoforos
0

Eu tive um problema semelhante com o seguinte não está funcionando ...

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

Isso funciona e sem a necessidade de uma extensão

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

Isso funciona também, mas provavelmente cai na categoria "looping manual" ....

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

Nova variável, dou o nome subString e coloco a string que você deseja pesquisar em alguns elementos do texto. Em seguida, usando o seletor Jquery, selecione os elementos que você precisa, como meu exemplo $("elementsYouNeed")e filtro .filter(). No .filter()ele irá comparar cada elemento $("elementsYouNeed")com a função.

Na função que estou usando .toLowerCase()para o texto do elemento, também subString, que pode evitar a distinção entre maiúsculas e minúsculas e verificar se há uma subString nela. Depois disso, o .filter()método constrói um novo objeto jQuery a partir de um subconjunto dos elementos correspondentes.

Agora você pode obter os elementos de correspondência no matchObjects e fazer o que quiser.

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

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