Wybierz link według tekstu (dopasowanie ścisłe)


89

Korzystając z jQuery, chcę wybrać łącze zawierające dokładnie jakiś tekst. Na przykład:

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

Próbowałem tego:

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

Ale wybiera pierwsze ORAZ drugie łącze. Chcę tylko pierwszego linku, który zawiera dokładnie „Ten”. Jak mogę to zrobić?


Odpowiedzi:


139

Możesz to zrobić:

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

Źródła: http://api.jquery.com/filter/


5
W tym przypadku w obu przypadkach działałoby, ale zwykle używam ===, ponieważ dopasowuje się do wartości i typu, tj. Nie wymusza typów. stackoverflow.com/questions/359494/…
FishBasketGordo,

1
Przegapiłeś return. Muszę to zmienić nafunction(index) { return (this.text === 'This One') }
Endy Tjahjono

Dodatkowo możesz sprawdzić długość tekstu.
bestinamir

39

Mój współpracownik rozszerzył jQuery o funkcję, która to robi:

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

W rezultacie możesz wybrać coś dokładnym tekstem w ten sposób:

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

Ułatwia to, ponieważ nie musisz za każdym razem pamiętać dokładnej składni. Cały jego post jest tutaj: jQuery Custom Selector do wybierania elementów według dokładnego tekstu: textEquals


28

Aby rozwinąć odpowiedź FishBasketGordo. Jeśli próbujesz dokonać wyboru na dużej liczbie elementów, użyj :contains()najpierw, aby zawęzić, a następnie zastosuj filtr.

Poprawi to ogólną prędkość:

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

Głosowano za szybkość / wydajność. Ponadto unika konieczności stosowania spacji $ .trim () w .filter (..).
JoePC

8

musiał zmodyfikować rozwiązanie Narimana, aby było:

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

W przeciwnym razie nie działało na Chrome (Linux)


6

Używałem rozszerzenia

$.expr[':'].textEquals

Ale odkryłem, że implementacja nie działa już z jQuery 1.7 (najwyraźniej zmiana w Sizzla.filter). Po pewnym czasie zmagania się, aby to działało, po prostu napisałem wtyczkę jQuery, aby osiągnąć to samo.

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

Posługiwać się:

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

Chciałem tylko udostępnić, na wypadek gdyby ktoś inny wpadł na to (,


3

Zatem odpowiedź Narniana działa całkiem nieźle. Używając go na wolności, napotkałem jednak pewne problemy, w których rzeczy, których bym się spodziewał, nie zostały znalezione. Dzieje się tak, ponieważ czasami istnieje przypadkowa biała przestrzeń otaczająca tekst elementu. Wierzę, że jeśli szukasz „Hello World”, nadal chciałbyś, aby pasowało do „Hello World”, a nawet „Hello World \ n”. Dlatego właśnie dodałem do funkcji metodę „trim ()”, która usuwa otaczające ją białe znaki i zaczęła działać lepiej. Ponadto zmodyfikowałem nazwy zmiennych, aby były trochę jaśniejsze dla mojego umysłu.

Konkretnie...

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

I uwaga dodatkowa ... przycinanie usuwa tylko białe znaki przed i po wyszukanym tekście. Nie usuwa białych znaków w środku słów. Uważam, że jest to pożądane zachowanie, ale możesz to zmienić, jeśli chcesz.


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

Czuję, że brakuje mi czegoś opartego na odpowiedziach wszystkich innych dotyczących filtrowania, ale dlaczego nie wybrać po prostu pierwszego elementu w tablicy elementów, który jest zwracany przez „zawiera”?

Działa to tylko wtedy, gdy wiesz, że pierwszy link ma dokładne dopasowanie, którego szukasz. Inne odpowiedzi działają lepiej, jeśli nie masz pewności, w jakiej kolejności będą znajdować się linki.


Ponieważ nie zawsze wie, że ten, którego chce, jest pierwszy
Cameron

Pytanie dotyczy konkretnie „Chcę tylko pierwszego linku”.
Michael Khalili

Pytanie prosi o dokładne dopasowanie, autor wskazuje pierwszy element, aby wyjaśnić, który element chce.
dlopezgonzalez

2

Jak uzyskać wybraną wartość z 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")); - zwróci wartość listy rozwijanej


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

1
Proszę dodać wyjaśnienie do odpowiedzi.
Michał Perłakowski

pierwsza linia, aby wybrać dowolny link z tym tekstem, druga i trzecia linia, co możesz zrobić z linkiem, aby je ukryć lub wyłączyć link, spójrz na filtr w dokumentacji jquery api.jquery.com/filter
David Fawzy

@DavidFawzy - przepraszam, umm ... co ?? Nie sądzę, aby druga lub trzecia linia miała cokolwiek wspólnego z pytaniem OP - to po prostu dodaje zamieszania.
jbyrd

2

Przepraszamy, jeśli to dokładnie pasuje do czyjejś odpowiedzi powyżej,

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

Oto niektóre dane wyjściowe w konsoli strony wyników wyszukiwania w serwisie 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

Obsługuje również rozróżnianie wielkości liter i nie używa :contains()

Edycja (22 maja 2017 r.): -

   $.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()
         }
      })
   }
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.