Виберіть елемент за точною відповідністю його вмісту


160

Гаразд, мені цікаво, чи є спосіб зробити так, щоб :contains()селектор jQuery вибирав елементи лише з рядком, який вводиться

наприклад -

<p>hello</p>
<p>hello world</p>

$('p:contains("hello")').css('font-weight', 'bold');

Селектор вибере обидва pелементи та зробить їх жирними, але я хочу, щоб він обрав лише перший.


Ну, ви можете перекрити :containsселектор власним кодом, але я не думаю, що це ви мали на увазі?
Blazemonger


Ви можете задати користувальницький селектор: stackoverflow.com/questions/12244929 / ...
BLSully

Можливий дублікат: Селектор Jquery, містить
рівну

можливий дублікат
Вибору

Відповіді:


214

Ні, немає жодного селектора jQuery (або CSS), який би це зробив.

Ви можете легко використовувати filter:

$("p").filter(function() {
    return $(this).text() === "hello";
}).css("font-weight", "bold");

Це не вибір , але це робить свою роботу. :-)

Якщо ви хочете обробити пробіл до або після "привіт", ви можете кинути $.trimтуди:

return $.trim($(this).text()) === "hello";

Для передчасних оптимізаторів там, якщо вам не байдуже, що вони не збігаються <p><span>hello</span></p>та подібні, ви можете уникнути дзвінків на $та безпосередньо, textвикористовуючи innerHTML:

return this.innerHTML === "hello";

... але для того, щоб мати значення, вам доведеться мати безліч абзаців, стільки, що, напевно, спочатку виникнуть інші проблеми. :-)


7
Можливо, ви хочете отримати $.trimбудь-яке бродяче пробіл, перш ніж робити порівняння.
Blazemonger

Мені чомусь довелося використовувати для цього "==", а не "===".
Стефан

3
@Stephan: Якщо ви порівнюєте число, вам доведеться або використовувати ==( == 2), або вводити число в рядок ( === "2"), оскільки значення, яке ви отримуєте від, text()або innerHTMLце завжди рядок. Якщо ви порівнювали рядок, не має значення, використовуєте ви ==чи ===.
TJ Crowder

Прикро, що jQuery реалізував :containsскладніші, але не застосував селектор для точного відповідності тексту. = {
Пауло Буено

54

Спробуйте додати функцію розширення псевдо:

$.expr[':'].textEquals = $.expr.createPseudo(function(arg) {
    return function( elem ) {
        return $(elem).text().match("^" + arg + "$");
    };
});

Тоді ви можете зробити:

$('p:textEquals("Hello World")');

2
чудове рішення: мало доповнення: щоб перезаписати наявний expr, я би зробив:$.expr[':'].textEquals = $.expr[':'].textEquals || $.expr.createPseudo(function(arg) {
Mischa Molhoek

9

Для цього можна скористатися функцією filter () jQuery .

$("p").filter(function() {
// Matches exact string   
return $(this).text() === "Hello World";
}).css("font-weight", "bold");

9

Тож відповідь Аманду здебільшого працює. Однак, використовуючи його в дикій природі, я зіткнувся з деякими проблемами, де речі, які я б очікував знайти, не знайдуться. Це було тому, що іноді є текст білого простору, що оточує текст елемента. Вважаю, що якщо ви шукаєте "Hello World", ви все одно хочете, щоб він відповідав "Hello World" або навіть "Hello World \ n". Таким чином, я просто додав метод "trim ()" до функції, який видаляє навколишній пробіл, і він почав працювати краще.

Зокрема ...

$.expr[':'].textEquals = function(el, i, m) {
    var searchText = m[3];
    var match = $(el).text().trim().match("^" + searchText + "$")
    return match && match.length > 0;
}

Також зауважте, ця відповідь надзвичайно схожа на Вибір посилання за текстом (точна відповідність)

І додаткова примітка ... trimвидаляє лише пробіли до та після пошуку тексту. Це не видаляє пробіли в середині слів. Я вважаю, що це бажана поведінка, але ви можете це змінити, якщо хочете.


5

Я знайшов спосіб, який працює для мене. Він не на 100% точний, але він виключає всі рядки, які містять більше, ніж просто слово, яке я шукаю, тому що я перевіряю, чи не містить рядки також окремі пробіли. До речі, вам не потрібні ці "". jQuery знає, що ви шукаєте рядок. Переконайтеся, що у частині: містить () є лише один пробіл, інакше він не працюватиме.

<p>hello</p>
<p>hello world</p>
$('p:contains(hello):not(:contains( ))').css('font-weight', 'bold');

І так, я знаю, що це не спрацює, якщо у вас є такі речі <p>helloworld</p>


1
Розумне використання простих збігів з містить (..) без використання фільтра чи розширення! Не буде працювати над тим, що потребує пробілів, у першому міститься (..), але намагаються знайти рішення для цього. Дякую!
JoePC

3

Як і TJ Crowder, зазначений вище, функція фільтра творить чудеса. У моєму конкретному випадку це не спрацювало для мене. Мені потрібно було шукати кілька таблиць та їх відповідних тегів td всередині div (у цьому випадку діалогового вікна jQuery).

$("#MyJqueryDialog table tr td").filter(function () {
    // The following implies that there is some text inside the td tag.
    if ($.trim($(this).text()) == "Hello World!") {
       // Perform specific task.
    }
});

Я сподіваюся, що це комусь корисно!


Я досить нова у jquery, але я думаю, що було б трохи краще використовувати кожен () замість filter (), оскільки мета фільтра - повернути підрив. Але натхненно вирішив рішення, оскільки у мене були ті ж самі питання :)
JeopardyTempest


-4

Тут допоможе .First ()

$('p:contains("hello")').first().css('font-weight', 'bold');

Звичайно ... в цьому конкретному випадку. що робити, якщо замовлення не відоме в розроблений час?
BLSully
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.