Выбрать ссылку по тексту (точное совпадение)

89

Используя jQuery, я хочу выбрать ссылку, которая содержит именно какой-то текст. Например:

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

Я пробовал это:

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

Но он выбирает первую И вторую ссылку. Мне просто нужна первая ссылка, которая содержит именно «Этот». Как я могу это сделать?

Энди Тьяджоно
источник

Ответы:

139

Ты можешь это сделать:

$('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') }
Энди Тьяджоно
Кроме того, вы можете проверить длину текста.
bestinamir
39

Мой коллега расширил jQuery функцией для этого:

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

В результате вы можете выбрать что-то по точному тексту следующим образом:

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

Это упрощает задачу, поскольку вам не нужно каждый раз запоминать точный синтаксис. Весь его пост находится здесь: jQuery Custom Selector для выбора элементов по точному тексту: 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;
}

И второе примечание ... обрезка удаляет только пробелы до и после искомого текста. Он не удаляет пробелы в середине слов. Я считаю, что это желательное поведение, но вы можете изменить это, если хотите.

bwest87
источник
3
$('a:contains("This One")')[0];

Я чувствую, что мне что-то не хватает, основываясь на ответах всех остальных на фильтрацию, но почему бы просто не выбрать первый элемент в массиве элементов, который возвращается с помощью 'contains'?

Это работает, только если вы знаете, что первая ссылка имеет точное совпадение, которое вы ищете. Другие ответы работают лучше, если вы не уверены, в каком порядке будут ссылки.

Майкл Халили
источник
Потому что он не всегда знает, что ему нужен первый
Кэмерон
Вопрос, в частности, спрашивает: «Мне просто нужна первая ссылка».
Майкл Халили
Вопрос требует точного совпадения, автор указывает первый элемент, чтобы объяснить, какой элемент хочет.
dlopezgonzalez
2

Как получить выбранное значение из выпадающего меню:

$.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
Пожалуйста, объясните свой ответ.
Michał Perłakowski
первая строка для выбора любой ссылки с этим текстом, вторая и третья строки, что вы можете сделать со ссылкой, чтобы скрыть их или отключить фильтр просмотра ссылок в документации jquery api.jquery.com/filter
Дэвид Фаузи,
@DavidFawzy - прости, ммм ... что ?? Я не думаю, что 2-я или 3-я строки имеют какое-либо отношение к вопросу OP - это просто добавляет путаницы.
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()
         }
      })
   }
Викас Гаутам
источник