Чи є нечутливий до випадку 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.