web-dev-qa-db-fra.com

Sélectionnez le lien par le texte (correspondance exacte)

Avec jQuery, je souhaite sélectionner un lien contenant exactement un type 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?

82
Endy Tjahjono

Tu peux le faire:

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

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

131
FishBasketGordo

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

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

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

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

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

37
Narnian

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

Cela améliorera la vitesse globale:

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

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 fonctionne pas sur chrome (Linux)

7
Archer

J'utilisais l'extension

$.expr[':'].textEquals

Mais j’ai constaté que l’implémentation ne fonctionnait plus avec jQuery 1.7 (apparemment un changement dans Sizzla.filter). Après avoir lutté pendant un certain temps pour que cela fonctionne, 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 se heurterait à cela (,

3
Alvis

Comment obtenir la valeur sélectionnée à partir d'une liste déroulante:

$.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 de la liste déroulante

1
Iulia Lucaciu

Donc, la réponse de Narnian fonctionne plutôt bien. En l'utilisant dans la nature, cependant, j'ai rencontré quelques problèmes, des choses que je m'attendais à trouver ne sont pas retrouvées. En effet, des espaces blancs aléatoires entourent parfois le texte de l'élément. Je suis convaincu que si vous recherchez "Hello World", vous voudrez quand même qu'il corresponde à "Hello World" ou même à "Hello World\n". Ainsi, je viens d’ajouter la méthode "trim ()" à la fonction, ce qui supprime les espaces blancs environnants, et cela a commencé à mieux fonctionner. De plus, j'ai modifié les noms de variables pour les rendre un peu plus claires.

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 la 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 crois que c'est un comportement souhaitable, mais vous pouvez le changer si vous le souhaitez.

1
bwest87
var link = $('a').filter(function(index) { return $(this).text() === "Availability"; });
 $(link).hide();
        $(link).removeAttr('href');
0
David Fawzy
$('a:contains("This One")')[0];

J'ai l'impression qu'il me manque un élément basé sur la réponse à filtrer de tout le monde, mais pourquoi ne pas sélectionner simplement le premier élément du tableau d'éléments renvoyé par 'contient'?

Cela ne fonctionne que si vous savez que le premier lien correspond exactement à votre recherche. Les autres réponses fonctionnent mieux, si vous n'êtes pas sûr de l'ordre dans lequel les liens seront.

0
Michael Khalili

Désolé, si cela correspond exactement à la réponse 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 quelques résultats 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()
         }
      })
   }
0
Vikas Gautam