Знайти текстовий рядок за допомогою jQuery?


241

Скажімо, на веб-сторінці є такий рядок, як "Я проста строка", який я хочу знайти. Як би я пішов про це за допомогою JQuery?

Відповіді:


327

jQuery має метод містить. Ось фрагмент для вас:

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

Селектор вище вибирає будь-який елемент, який містить цільовий рядок. Foundin буде об’єктом jQuery, який містить будь-який збіглий елемент. Інформацію про API див. На веб-сторінці : https://api.jquery.com/contains-selector/

Одне, що слід зауважити під символом '*', - це те, що ви отримаєте всі елементи, включаючи ваш html елементи тіла, які, напевно, не хочете. Ось чому більшість прикладів у jQuery та інших місцях використовують $ ('div: містить ("Я проста строка")')


12
@ Тоні, як би я почав маніпулювати лише відповідним текстом, а не лише усім параграфом, дівом тощо тощо?
— Кіт Донеган

12
Слід зазначити, що це залежно від регістру. Користувач на ім’я "я" написав це на сторінці документів jQuery: $ .expr [':']. Icontains = функція (obj, індекс, мета, стек) {return (obj.textContent || obj.innerText || jQuery ( obj) .text () || '') .toLowerCase (). indexOf (meta [3] .toLowerCase ())> = 0; }; Приклад: $ ("div: icontains ('John") "). Css (" прикраса тексту "," підкреслити ");
— Брендон Блум

це працює для json? Що робити, якщо я хочу відфільтрувати текст у значенні json?
— Чамілян

5
Це не працюватиме, якщо у текстового вузла є розрив рядка, наприклад. "Я простий \ n рядок". Зауважте, що розрив рядка не буде наданий, тому користувач навіть не дізнається, де проблема. Усі ці рішення мають цю проблему. Див jsfiddle.net/qPeAx
— Jesper

9
-1, не працює. Він повертає всі батьківські вузли на дереві, потрібно лише найнижчий.
— TMS

51

Зазвичай селектори jQuery не здійснюють пошук у "текстових вузлах" у DOM. Однак якщо ви використовуєте функцію .contents (), текстові вузли будуть включені, то ви можете використовувати властивість nodeType для фільтрації лише текстових вузлів, а властивість nodeValue для пошуку текстового рядка.

    $ ('*', 'body')
        .andSelf ()
        .contents ()
        .filter (function () {
            повернути цей.nodeType === 3;
        })
        .filter (function () {
            // Збігається лише тоді, коли в тексті міститься "проста рядок"
            повернути this.nodeValue.indexOf ('проста рядок')! = -1;
        })
        .each (function () {
            // Зробіть щось із цим.nodeValue
        });

8
Для уточнення, як згадував Тоні, ви можете використовувати селектор ": містить ()" для пошуку в текстових вузлах, але jQuery не поверне окремі текстові вузли в результатах (лише список елементів). Але коли ви використовуєте .contents (), тоді jQuery повертає і елементи, і текстові вузли. Для отримання додаткової інформації: docs.jquery.com/Traversing/contents
— BarelyFitz

5
Мене спантеличує, чому ви користуєтесь .andSelf(). З api.jquery.com/andSelf : "Об'єкти jQuery підтримують внутрішній стек, який відстежує зміни в зібраному наборі елементів. Коли викликається один із методів обходу DOM, новий набір елементів висувається на стек. Якщо попередній набір елементів також бажаний .andSelf () може допомогти. " Я не бачу попереднього контексту, чого я пропускаю?
— Алан Х.

1
Оголошено! Це має бути прийнятою відповіддю, оскільки вона фільтрує всі батьківські вузли, які, на мою думку, є загальною потребою в більшості сценаріїв.
— ЛукаМ

29

Тут виберуть лише елементи листя, які містять "Я проста строка".

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

Вставте наступне в адресний рядок, щоб перевірити його.

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

Якщо ви хочете схопити просто "Я проста струна" . Спочатку загортайте текст у такий елемент.

$('*: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>' 
               )  
           ) 
});

а потім зробіть це.

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

3
тут функція .filter () була б кориснішою, ніж .each (). Насправді ви насправді можете вкласти його в один селектор: "*: містить (" бла "): порожній"
— nickf

2
# nickf -: порожній звичай не вибирає текстовий вузол, який містить текст. Отже, якщо текстовий вузол містить "Я - простий рядок", він виключається. docs.jquery.com/Selectors/empty
— Тонкий

2
Я знаю, що я трохи запізнююся тут, але чи не буде це ігноровано жодних текстових блоків, де рядок існує на верхньому рівні, але в ньому є діти? наприклад: <blockquote> Я проста рядок <span style = "font-weight: bold;"> ЖИТТЯ НА РОЗІ </span> </blockquote>
— Кен Беллоуз

Я просто хочу зазначити, що "міститьStringImLookingFor" не є дійсним HTML-атрибутом. Будь ласка, використовуйте для HTML 5 "data-containsStringImLookingFor". Немає можливості для версії HTML раніше, ніж 5, додати спеціальні атрибути ...
— Snickbrack,

17

Якщо ви просто хочете, щоб вузол був найближчим до тексту, який ви шукаєте, ви можете скористатися цим:

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

Це навіть спрацює, якщо ваш HTML виглядає так:

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

Використовуючи вищевказаний селектор, ви знайдете <strong>тег, оскільки це останній тег, який містить всю цю рядок.


1
Це, здається, не працює. Наприклад, на цій сторінці *: містить ("the"): останній повертає лише 1 елемент.
— bzlm

4
@bzlm: добре, це не обов'язково вказувало, що він хотів знайти кілька випадків.
— nickf

2
Ага. Чи є спосіб змусити його працювати для кількох випадків? Я думаю, що це більш елегантне рішення, ніж ті, що стосуються рекурсивної перевірки типу вузлів тощо.
— bzlm

1
єдиний спосіб я міг би подумати, щоб отримати всі вузли, але не всі предки піднімаються в рядку - це провести цикл через результат, видаливши всіх батьків, хоча у вас можуть виникнути проблеми, наприклад: <p>my text <b>my text</b></p>- видалення предків <b>тегу програють інший матч
— nickf


7

Просто додавши відповідь Тоні Міллера, оскільки це наділило мене на 90% до того, що я шукав, але все одно не працював. Додавши .length > 0;до кінця свого коду, мій сценарій запрацював.

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

як додати нове слово до знайденого рядка ?, я хочу додати зірочку до знайденої роботи.
— користувачAZLogicApps

@SaMolPP foundin += '*';
— Pixelomo

2

ця функція повинна працювати. в основному відбувається рекурсивний пошук, поки ми не отримаємо чіткого списку вузлів листя.

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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.