Виберіть посилання за текстом (точна відповідність)


89

За допомогою jQuery я хочу вибрати посилання, яке містить точно якийсь текст. Наприклад:

<p><a>This One</a></p>
<p><a>"This One?"</a></p>
<p><a>Unlikely</a></p>

Я спробував це:

$('a:contains("This One")')

Але він вибирає перше І друге посилання. Я просто хочу перше посилання, яке містить саме "Цей". Як я можу це зробити?


Відповіді:


138

Ви можете зробити це:

$('a').filter(function(index) { return $(this).text() === "This One"; });

Довідково: http://api.jquery.com/filter/


5
Будь-яке з них працювало б у цьому випадку, але я, як правило, використовую ===, оскільки воно збігається за значенням і типом, тобто не примушує типи. stackoverflow.com/questions/359494 / ...
FishBasketGordo

1
Ви пропустили return. Я повинен змінити його наfunction(index) { return (this.text === 'This One') }
Endy Tjahjono

Крім того, ви можете перевірити довжину тексту.
bestinamir

39

Мой колега розширив jQuery з функцією для цього:

$.expr[':'].textEquals = function(a, i, m) {
    return $(a).text().match("^" + m[3] + "$");
};

У результаті ви можете вибрати щось за точним текстом таким чином:

$("label:textEquals('Exact Text to Match')");

Це полегшує роботу, оскільки вам не потрібно запам’ятовувати точний синтаксис кожного разу. Весь його допис тут: Спеціальний селектор jQuery для вибору елементів за точним текстом: textEquals


28

Розширити відповідь FishBasketGordo. Якщо ви намагаєтеся зробити вибір на великій кількості елементів, :contains()спочатку скористайтеся звуженням, а потім застосуйте фільтр.

Це покращить загальну швидкість:

$('a:contains("This One")').filter(function(index)
{
    return $(this).text() === "This One";
});

Проголосував за швидкість / ефективність. Крім того, уникає необхідності пробілів $ .trim () у межах .filter (..).
JoePC

8

довелося змінити рішення Нарімана таким чином:

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

Інакше не працював на chrome (Linux)


6

Я використовував розширення

$.expr[':'].textEquals

Але я виявив, що реалізація більше не працює з jQuery 1.7 (очевидно, зміна в Sizzla.filter). Протягом деякого часу намагаючись змусити це працювати, я просто написав плагін jQuery, щоб виконати те саме.

$.fn.textEquals = function (text) {
    var match = false;
    $(this).each(function () {
        if ($(this).text().match("^" + escapeRegex(text) + "$")) {
            match = true;
            return false;
        }
    });
    return match;
};

Використання:

$(".ui-autocomplete li").textEquals('Exact Text to Match');

Просто хотів поділитися, на випадок, якщо хтось наткнеться на це (,


3

Тож відповідь Нарніяна працює досить добре. Однак, використовуючи його в дикій природі, я зіткнувся з деякими проблемами, де речі, які я очікував би знайти, не знаходились. Це було тому, що іноді навколо тексту елемента є випадковий пробіл. Я вважаю, що якщо ви шукаєте "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;
}

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


3
$('a:contains("This One")')[0];

Я відчуваю, що мені щось не вистачає на основі відповіді всіх інших для фільтрування, але чому б просто не вибрати перший елемент у масиві елементів, що повертається через "містить"?

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


Оскільки він не завжди знає, що той, кого хоче, є першим
Камерон

Питання конкретно задає "Я просто хочу перше посилання".
Michael Khalili

Питання задає точну відповідність, автор вказує перший елемент, щоб пояснити, який елемент хоче.
dlopezgonzalez

2

Як отримати вибране значення за допомогою drop-dwon:

$.fn.textEquals = function (text) {
    var match = false; 
    var values="";
    $(this).each(function () {
        if ($(this).text().match("^" + text + "$")) {
            values=$(this).val();
            match = true;
            return false;
        }
    });
    return values;
};

console.log($("option").textEquals("Option One")); - поверне значення випадаючого списку


2
var link = $('a').filter(function(index) { return $(this).text() === "Availability"; });
 $(link).hide();
        $(link).removeAttr('href');

1
Будь ласка, додайте пояснення до своєї відповіді.
Міхал Перлаковський

перший рядок, щоб вибрати будь-яке посилання з цим текстом, другий та третій рядки, що ви можете зробити із посиланням, щоб приховати їх або відключити посилання, подивіться на фільтр у документації jquery api.jquery.com/filter
Девід Фаузі

@DavidFawzy - вибачте, ммм ... що ?? Я не думаю, що 2-й чи 3-й рядки мають нічого спільного з питанням ОП - це просто додає сум'яття.
jbyrd

2

Вибачте, якщо це точно відповідає будь-якій відповіді вище,

   $.fn.equalsText = function (text, isCaseSensitive) {
      return $(this).filter(function () {
         if (isCaseSensitive) {
            return $(this).text() === text
         } else {
            return $(this).text().toLowerCase() === text.toLowerCase()
         }
      })
   }

Ось деякі результати на консолі сторінки результатів пошуку Linkedin.

$("li").equalsText("Next >", false)
[<li class=​"next">​…​</li>​] // Output

$("li").equalsText("next >", false)
[<li class=​"next">​…​</li>​] // Output

$("li").equalsText("Next >", true)
[<li class=​"next">​…​</li>​] // Output

$("li").equalsText("next >", true)
[] // Output

Він також має підтримку чутливості до регістру і не використовує :contains()

Редагувати (22 травня 2017 р.): -

   $.fn.equalsText = function (textOrRegex, isCaseSensitive) {
      return $(this).filter(function () {
         var val = $(this).text() || this.nodeValue
         if (textOrRegex instanceof RegExp) {
            return textOrRegex.test(val)
         } else if (isCaseSensitive) {
            return val === textOrRegex
         } else {
            return val.toLowerCase() === textOrRegex.toLowerCase()
         }
      })
   }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.