Trova una stringa di testo usando jQuery?


241

Supponiamo che una pagina web abbia una stringa come "I am a simple string" che voglio trovare. Come potrei fare questo usando JQuery?

Risposte:


327

jQuery ha il metodo contiene. Ecco un frammento per te:

<script type="text/javascript">
$(function() {
    var foundin = $('*:contains("I am a simple string")');
});
</script>

Il selettore sopra seleziona qualsiasi elemento che contiene la stringa di destinazione. Il foundin sarà un oggetto jQuery che contiene qualsiasi elemento corrispondente. Consulta le informazioni sull'API su: https://api.jquery.com/contains-selector/

Una cosa da notare con il carattere jolly '*' è che otterrai tutti gli elementi, incluso il tuo html e gli elementi del corpo, che probabilmente non vuoi. Ecco perché la maggior parte degli esempi su jQuery e in altri luoghi usa $ ('div: contiene ("I am a simple string")')


12
@Tony, come potrei fare per manipolare solo il testo corrispondente e non solo l'intero parapgraph, div ecc ecc?
Keith Donegan,

12
Dovrebbe sottolineare che questo è sensibile al maiuscolo / minuscolo. Un utente di nome "me" ha scritto questo sulla pagina dei documenti di jQuery: $ .expr [':']. Icontains = function (obj, index, meta, stack) {return (obj.textContent || obj.innerText || jQuery ( obj) .text () || '') .toLowerCase (). indexOf (meta [3] .toLowerCase ())> = 0; }; Esempio: $ ("div: icontains ('John')"). Css ("text-decoration", "underline");
Brandon Bloom,

funziona per JSON? E se volessi filtrare del testo in un valore json?
Chamilyan,

5
Questo non funzionerà se il nodo di testo presenta un'interruzione di riga, ad es. "Sono una stringa semplice \ n". Si noti che l'interruzione di riga non verrà renderizzata, quindi l'utente non saprà nemmeno dove si trova il problema. Tutte queste soluzioni hanno questo problema. Vedi jsfiddle.net/qPeAx
jesper

9
-1, non funziona. Restituisce tutti i nodi padre nella struttura, si desidera solo il più basso.
TMS

51

Normalmente i selettori jQuery non effettuano ricerche all'interno dei "nodi di testo" nel DOM. Tuttavia, se si utilizza la funzione .contents (), verranno inclusi i nodi di testo, quindi è possibile utilizzare la proprietà nodeType per filtrare solo i nodi di testo e la proprietà nodeValue per cercare la stringa di testo.

    $ ('*', 'body')
        .andSelf ()
        .Contenuti()
        .filter (function () {
            restituisce this.nodeType === 3;
        })
        .filter (function () {
            // Corrisponde solo quando contiene "stringa semplice" in qualsiasi punto del testo
            restituisce this.nodeValue.indexOf ('stringa semplice')! = -1;
        })
        .each (function () {
            // Fai qualcosa con this.nodeValue
        });

8
Per chiarire, come ha detto Tony, puoi usare il selettore ": Includes ()" per cercare all'interno dei nodi di testo, ma jQuery non restituirà i singoli nodi di testo nei risultati (solo un elenco di elementi). Ma quando usi .contents (), jQuery restituisce sia elementi che nodi di testo. Per maggiori informazioni: docs.jquery.com/Traversing/contents
BarelyFitz,

5
Sono perplesso dal motivo per cui stai usando .andSelf(). Da api.jquery.com/andSelf : "Gli oggetti jQuery mantengono uno stack interno che tiene traccia delle modifiche al set di elementi abbinato. Quando viene chiamato uno dei metodi di attraversamento DOM, il nuovo set di elementi viene inserito nello stack. Se si desidera anche il set di elementi precedente, .andSelf () può aiutare. " Non vedo alcun contesto precedente, cosa mi sto perdendo?
Alan H.

1
Upvoted! Dovrebbe essere la risposta accettata perché filtra tutti i nodi padre che ritengo sia il bisogno comune nella maggior parte degli scenari.
Luca,

29

Questo selezionerà solo gli elementi foglia che contengono "I am a simple string".

$('*:contains("I am a simple string")').each(function(){
     if($(this).children().length < 1) 
          $(this).css("border","solid 2px red") });

Incolla quanto segue nella barra degli indirizzi per testarlo.

javascript: $('*:contains("I am a simple string")').each(function(){ if($(this).children().length < 1) $(this).css("border","solid 2px red") }); return false;

Se vuoi prendere solo "I am a simple string" . Prima avvolgi il testo in un elemento come questo.

$('*:contains("I am a simple string")').each(function(){
     if($(this).children().length < 1) 
          $(this).html( 
               $(this).text().replace(
                    /"I am a simple string"/
                    ,'<span containsStringImLookingFor="true">"I am a simple string"</span>' 
               )  
           ) 
});

e poi fai questo.

$('*[containsStringImLookingFor]').css("border","solid 2px red");

3
la funzione .filter () sarebbe più utile di .each () qui. In effetti, potresti effettivamente inserirlo in un solo selettore: "*: contiene ('blah'): vuoto"
nickf

2
#nickf -: vuoto non seleziona un nodo di testo che contiene testo. Quindi, se il nodo di testo contiene "I am a simple string", viene escluso. docs.jquery.com/Selectors/empty
Slim

2
So di essere un po 'in ritardo qui, ma questo non ignorerà i blocchi di testo in cui la stringa esiste al livello più alto ma ci sono dei bambini al suo interno? es: <blockquote> Sono una stringa semplice <span style = "font-weight: bold;"> VIVERE SUL BORDO </span> </blockquote>
Ken Bellows

Voglio solo ricordare che "IncludesStringImLookingFor" non è un attributo HTML valido. Si prega di utilizzare per HTML 5 "data-IncludesStringImLookingFor". Per la versione HTML precedente alla 5 non è possibile aggiungere attributi personalizzati ...
Snickbrack,

17

Se vuoi solo il nodo più vicino al testo che stai cercando, puoi usare questo:

$('*:contains("my text"):last');

Funzionerà anche se il tuo HTML è simile al seguente:

<p> blah blah <strong>my <em>text</em></strong></p>

Usando il selettore sopra troverai il <strong>tag, dato che è l'ultimo tag che contiene l'intera stringa.


1
Questo non sembra funzionare. In questa pagina, ad esempio, *: contiene ("il"): last restituisce solo 1 elemento.
bzlm,

4
@bzlm: beh, non ha necessariamente specificato che voleva trovare più occorrenze.
Nickf

2
Aha. C'è un modo per farlo funzionare per più occorrenze? Penso che sia una soluzione più elegante di quelle che coinvolgono il controllo del tipo di nodo ricorsivo ecc.
bzlm

1
l'unico modo in cui potrei pensare di ottenere tutti i nodi, ma non tutti gli antenati lungo la linea sarebbe quello di scorrere il risultato, rimuovendo tutti i genitori, anche se potresti avere problemi, ad esempio: <p>my text <b>my text</b></p>- rimuovere gli antenati del <b>tag sarebbe perde l'altra partita
nickf


7

Sto solo aggiungendo alla risposta di Tony Miller perché questo mi ha portato il 90% verso quello che stavo cercando ma che ancora non ha funzionato. L'aggiunta .length > 0;alla fine del suo codice ha fatto funzionare il mio script.

 $(function() {
    var foundin = $('*:contains("I am a simple string")').length > 0;
 });

come aggiungere una nuova parola sulla stringa trovata?, voglio aggiungere un asterisco a quel lavoro trovato.
userAZLogicApps

@SaMolPP foundin += '*';
Pixelomo

2

questa funzione dovrebbe funzionare. fondamentalmente esegue una ricerca ricorsiva fino a quando non otteniamo un elenco distinto di nodi foglia.

function distinctNodes(search, element) {
    var d, e, ef;
    e = [];
    ef = [];

    if (element) {
        d = $(":contains(\""+ search + "\"):not(script)", element);
    }
    else {
            d = $(":contains(\""+ search + "\"):not(script)");
    }

    if (d.length == 1) {
            e.push(d[0]);
    }
    else {
        d.each(function () {
            var i, r = distinctNodes(search, this);
            if (r.length === 0) {
                e.push(this);
            }
            else {
                for (i = 0; i < r.length; ++i) {
                    e.push(r[i]);
                }
            }
        });
    }
    $.each(e, function () {
        for (var i = 0; i < ef.length; ++i) {
            if (this === ef[i]) return;
        }
        ef.push(this);
    });
    return ef;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.