Sélectionnez le lien par texte (correspondance exacte)


89

En utilisant jQuery, je souhaite sélectionner un lien qui contient exactement une sorte de texte. Par exemple:

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

J'ai essayé ceci:

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

Mais il choisit le premier ET le deuxième lien. Je veux juste le premier lien, qui contient exactement "Celui-ci". Comment puis je faire ça?


Réponses:


138

Tu peux le faire:

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

Référence: http://api.jquery.com/filter/


5
Les deux fonctionneraient dans ce cas, mais j'ai tendance à utiliser === car il correspond à la valeur et au type, c'est-à-dire qu'il ne contraindra pas les types. stackoverflow.com/questions/359494/…
FishBasketGordo

1
Vous avez manqué return. Je dois le changer pourfunction(index) { return (this.text === 'This One') }
Endy Tjahjono

En outre, vous pouvez vérifier la longueur du texte.
bestinamir

39

Un de mes collègues a étendu jQuery avec une fonction pour faire ceci:

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

Le résultat est que vous pouvez sélectionner quelque chose par texte exact de cette façon:

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

Cela facilite les choses, car vous n'avez pas à vous souvenir de la syntaxe exacte à chaque fois. Son article entier est ici: jQuery Custom Selector pour sélectionner des éléments par texte exact: textEquals


28

Pour développer la réponse de FishBasketGordo. Si vous essayez de faire la sélection sur une grande quantité d'éléments, utilisez d' :contains()abord pour affiner, puis appliquez le filtre.

Cela améliorera la vitesse globale:

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

Voté pour la vitesse / efficacité. De plus, évite le besoin d'espaces $ .trim () dans .filter (..).
JoePC

8

a dû modifier la solution de Nariman pour être:

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

Sinon, ne fonctionnait pas sur Chrome (Linux)


6

J'utilisais l'extension

$.expr[':'].textEquals

Mais j'ai trouvé que l'implémentation ne fonctionne plus avec jQuery 1.7 (apparemment un changement dans Sizzla.filter). Après avoir lutté pendant un certain temps pour le faire fonctionner, j'ai simplement écrit un plugin jQuery pour accomplir la même chose.

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

Utilisation:

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

Je voulais juste partager, au cas où quelqu'un d'autre rencontrerait ceci (,


3

La réponse de Narnian fonctionne donc plutôt bien. En l'utilisant dans la nature, cependant, j'ai rencontré des problèmes, où les choses que je m'attendais à trouver ne l'étaient pas. En effet, parfois, il y a un espace blanc aléatoire entourant le texte de l'élément. Je pense que si vous recherchez "Hello World", vous voudrez toujours qu'il corresponde à "Hello World", ou même "Hello World \ n". Ainsi, je viens d'ajouter la méthode "trim ()" à la fonction, qui supprime les espaces blancs environnants, et cela a commencé à mieux fonctionner. De plus, j'ai modifié les noms des variables pour être un peu plus clairs dans mon esprit.

Plus précisément...

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

Et note secondaire ... trim ne supprime que les espaces avant et après le texte recherché. Il ne supprime pas les espaces au milieu des mots. Je pense que c'est un comportement souhaitable, mais vous pouvez changer cela si vous le souhaitez.


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

J'ai l'impression que je manque quelque chose en fonction de la réponse de tout le monde à filtrer, mais pourquoi ne pas simplement sélectionner le premier élément dans le tableau d'éléments retourné par «contient»?

Cela ne fonctionne que si vous savez que le premier lien a la correspondance exacte que vous recherchez. Les autres réponses fonctionnent mieux, si vous ne savez pas dans quel ordre les liens seront.


Parce qu'il ne sait pas toujours celui qu'il veut, c'est le premier
Cameron

La question demande spécifiquement "Je veux juste le premier lien".
Michael Khalili

La question demande la correspondance exacte, l'auteur indique le premier élément pour expliquer quel élément veut.
dlopezgonzalez

2

Comment obtenir la valeur sélectionnée à partir d'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")); - il retournera la valeur du menu déroulant


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

1
Veuillez ajouter une explication à votre réponse.
Michał Perłakowski

la première ligne pour sélectionner n'importe quel lien avec ce texte, deuxième et troisième lignes que pouvez-vous faire avec le lien pour les masquer ou désactiver le lien regarder le filtre dans la documentation jquery api.jquery.com/filter
David Fawzy

@DavidFawzy - désolé, euh ... quoi ?? Je ne pense pas que les 2e ou 3e lignes aient quoi que ce soit à voir avec la question du PO - cela ne fait qu'ajouter à la confusion.
jbyrd

2

Désolé, si cela correspond exactement à la réponse de quelqu'un ci-dessus,

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

Voici une sortie dans la console de la page de résultats de recherche 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

Il prend également en charge la sensibilité à la casse et n'utilise pas :contains()

Edit (22 mai 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()
         }
      })
   }
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.