Seleccionar enlace por texto (coincidencia exacta)


89

Usando jQuery, quiero seleccionar un enlace que contenga exactamente algún tipo de texto. Por ejemplo:

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

He intentado esto:

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

Pero elige el primer Y el segundo enlace. Solo quiero el primer enlace, que contiene exactamente "Este". ¿Cómo puedo hacer eso?


Respuestas:


138

Puedes hacerlo:

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

Referencia: http://api.jquery.com/filter/


5
Cualquiera de los dos funcionaría en este caso, pero tiendo a usar === porque coincide con el valor y el tipo, es decir, no coaccionará los tipos. stackoverflow.com/questions/359494/…
FishBasketGordo

1
Te perdiste return. Tengo que cambiarlo afunction(index) { return (this.text === 'This One') }
Endy Tjahjono

Además, puede verificar la longitud del texto.
bestinamir

39

Un compañero de trabajo extendió jQuery con una función para hacer esto:

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

El resultado es que puede seleccionar algo por texto exacto de esta manera:

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

Esto lo hace fácil, ya que no tiene que recordar la sintaxis exacta cada vez. Su publicación completa está aquí: jQuery Custom Selector para seleccionar elementos por texto exacto: textEquals


28

Para ampliar la respuesta de FishBasketGordo. Si está intentando hacer la selección en una gran cantidad de elementos, utilice :contains()primero para reducir y luego aplique el filtro.

Esto mejorará la velocidad general:

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

Votado por velocidad / eficiencia. Además, evita la necesidad de espacios $ .trim () dentro de .filter (..).
JoePC

8

tuvo que modificar la solución de Nariman para ser:

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

De lo contrario, no funcionó en Chrome (Linux)


6

Estaba usando la extensión

$.expr[':'].textEquals

Pero descubrí que la implementación ya no funciona con jQuery 1.7 (aparentemente un cambio en Sizzla.filter). Después de luchar durante un tiempo para que funcione, simplemente escribí un complemento jQuery para lograr lo mismo.

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

Utilizar:

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

Solo quería compartir, en caso de que alguien más se encuentre con esto (,


3

Entonces, la respuesta de Narnian funciona bastante bien. Sin embargo, al usarlo en la naturaleza, me encontré con algunos problemas, en los que no se encontraban las cosas que esperaba encontrar. Esto se debe a que a veces hay espacios en blanco aleatorios alrededor del texto del elemento. Creo que si estás buscando "Hello World", aún querrás que coincida con "Hello World" o incluso con "Hello World \ n". Por lo tanto, acabo de agregar el método "trim ()" a la función, que elimina los espacios en blanco circundantes, y comenzó a funcionar mejor. Además, modifiqué los nombres de las variables para que fueran un poco más claros en mi mente.

Específicamente...

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

Y nota secundaria ... recortar solo elimina los espacios en blanco antes y después del texto buscado. No elimina los espacios en blanco en medio de las palabras. Creo que este es un comportamiento deseable, pero podrías cambiarlo si quisieras.


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

Siento que me falta algo basado en la respuesta de todos los demás al filtro, pero ¿por qué no seleccionar el primer elemento dentro de la matriz de elementos que devuelve 'contiene'?

Esto funciona, solo si sabe que el primer enlace tiene la coincidencia exacta que está buscando. Otras respuestas funcionan mejor si no está seguro de en qué orden estarán los enlaces.


Porque no siempre sabe que el que quiere es el primero
Cameron

La pregunta pregunta específicamente "Solo quiero el primer enlace".
Michael Khalili

La pregunta pide la coincidencia exacta, el autor indica el primer elemento para explicar qué elemento quiere.
dlopezgonzalez

2

Cómo obtener el valor seleccionado de un 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")); - devolverá el valor del menú desplegable


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

1
Agregue una explicación a su respuesta.
Michał Perłakowski

la primera línea para seleccionar cualquier enlace con ese texto, segunda y tercera líneas, ¿qué puede hacer con el enlace para ocultarlos o deshabilitar el enlace? Ver el filtro en la documentación de jquery api.jquery.com/filter
David Fawzy

@DavidFawzy - lo siento, umm ... ¿qué ?? No creo que la segunda o la tercera línea tengan nada que ver con la pregunta del OP, solo agrega confusión.
jbyrd

2

Lo siento, si esto coincide exactamente con la respuesta anterior de alguien,

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

Aquí hay algunos resultados en la consola de la página de resultados de búsqueda de 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

También tiene compatibilidad con mayúsculas y minúsculas y no utiliza :contains()

Editar (22 de mayo de 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()
         }
      })
   }
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.