Чи є нечутливий до випадку jQuery: містить селектор?


145

Чи є нечутлива до регістру версія : містить селектор jQuery або я повинен виконувати роботу вручну, перебираючи всі елементи та порівнюючи їх .text () зі своєю строкою?


2
Для jQuery 8.1 + перевірте цю відповідь
Praveen

1
^ Це 1.8.1, а не 8.1.
TylerH

Хороший приклад тут .
劉鎮 瑲

Відповіді:


125

Що я в кінцевому підсумку робив для jQuery 1.2:

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

Це поширить jquery, щоб він мав: Містить селектор, нечутливий до регістру, селектор: містить залишається незмінним.

Редагувати: для jQuery 1.3 (спасибі @ user95227) і пізніше вам потрібно

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

Редагувати: мабуть, безпосередньо ви можете отримати доступ до DOM за допомогою

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

замість

jQuery(a).text()

У попередньому виразі це значно прискорює, тому спробуйте на власний ризик, якщо швидкість є проблемою. (див . запитання @John )

Остання редакція: Для jQuery 1.8 слід:

jQuery.expr[":"].Contains = jQuery.expr.createPseudo(function(arg) {
    return function( elem ) {
        return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
    };
});

Я просто хотів повідомити людям, що рішення, описане @Pat та іншими для jQuery 1.3, також працює для 1.4.3.
Jim Ade

Посилання на @ Джон питання / відповідь , так як посилання тут був видалений: stackoverflow.com/questions/1407434 / ...
Mottie

Це не працює для jQuery 1.8. Дивіться відповідь seagullJS нижче для оновленої версії - stackoverflow.com/a/12113443/560114
Метт Браун

105

Щоб зробити його необов'язковим до регістру: 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;
  }
});

тоді використовуйте :containsiзамість:contains


3
додавання нової функції найкраще, ніж перезапис для мене, я зараз використовую цю опцію (працює як шарм)
GôTô

22
це слід додати до стандартної бібліотеки jquery
user482594

41

Станом на jQuery 1.3 цей метод застарілий. Для того, щоб це працювало, його потрібно визначити як функцію:

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

38

Якщо когось (як я) цікавить, що означають a і m [3] у визначенні Містить .


КЛЮЧ / ЛЕГЕНД: Параметри, доступні jQuery для використання у визначеннях селектора:

r = jQuery масив елементів, які перевіряються. (наприклад: r.length = Кількість елементів)

i = індекс елемента, що знаходиться під контролем, в масиві r .

а = елемент, який зараз переглядається. Оператор Selector повинен повернути true, щоб включити його у відповідні результати.

м [2] = nodeName або *, що ми шукаємо (зліва від двокрапки).

m [3] = парам перейшов у: селектор (парам). Зазвичай індексне число, як у : nth-of-type (5) або рядок, як у : color (blue) .


31

У jQuery 1.8 вам потрібно буде скористатися

jQuery.expr[":"].icontains = jQuery.expr.createPseudo(function (arg) {                                                                                                                                                                
    return function (elem) {                                                            
        return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;        
    };                                                                                  
});

2
Працювали чудово, дякую! Щойно оновлено до 1,8, і це перестало працювати.
Андреас

3
ніж за оновлення. Щойно оновлений до JQuery 1.8, і він перестав працювати
Васим

15

Варіант, який, здається, працює трохи швидше і який також дозволяє регулярні вирази :

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



Це не лише чутливість до регістру, але й дозволяє потужні пошуки:

  • $("p:containsCI('\\bup\\b')") (Відповідає "Вгору" або "вгору", але не "верхній", "прокидання" тощо)
  • $("p:containsCI('(?:Red|Blue) state')") (Відповідає "червоний стан" або "синій стан", але не "стан штату" тощо)
  • $("p:containsCI('^\\s*Stocks?')") (Відповідає "запас" або "запас", але лише на початку абзацу (ігноруючи будь-які провідні пробіли).)

11

Може пізно .... але,

Я вважаю за краще піти цим шляхом ..

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

Таким чином, ви НЕ підробляєте NATIVE '.contains' jQuery ... Можливо, вам знадобиться за замовчуванням пізніше ... якщо ви будете підроблені, ви можете повернутися до stackOverFlow ...


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

Код оновлення чудово працює в 1.3, але "містить" має бути малі літери на першій букві на відміну від попереднього прикладу.


1
Я думаю, що він хотів чітко функціонувати, щоб :containsі :Containsобидва працювали одночасно.
joshperry

"селектор містить: залишається незмінним."
Гаррі Б

4

Нижче описано, щоб використовувати текст ": містить", щоб знайти текст, ігноруючи його чутливість до регістру, з 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");
          }              
        });

Ви також можете скористатися цим посиланням, щоб знайти код ігнорування регістру на основі версії jquery, Зробити jQuery: містить регістр справ


2

Більш швидка версія з використанням регулярних виразів.

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

Відмінна робота! Велике спасибі. Я вважаю, що це найкраща та найсучасніша відповідь на це питання.
mavrosxristoforos

0

У мене була подібна проблема з наступними не працюючими ...

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

Це працює і без необхідності розширення

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

Це теж працює, але, ймовірно, потрапляє в категорію "вручну".

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

0

Нова змінна Я даю їй ім'я subString і ставлю рядок, який потрібно шукати в тексті деяких елементів. Потім за допомогою селектора Jquery виберіть елементи, які вам потрібні, наприклад, мій приклад $("elementsYouNeed")та фільтруйте по .filter(). У .filter()ньому буде порівнюватися кожен елемент в$("elementsYouNeed") функції з функцією.

У функції, яку я використовую .toLowerCase()для тексту елемента, також є subString, що дозволяє уникнути чутливого до регістру стану та перевірити, чи є в ньому subString. Після цього .filter()метод будує новий об'єкт jQuery з підмножини відповідних елементів.

Тепер ви можете отримати елементи матчу у matchObjects та робити все, що завгодно.

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

var matchObjects = $("elementsYouNeed").filter(function () {return $(this).text().toLowerCase().indexOf(subString) > -1;});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.