Использование .text () для извлечения только текста, не вложенного в дочерние теги - PullRequest
350 голосов
/ 09 августа 2010

Если у меня html вот так:

<li id="listItem">
    This is some text
    <span id="firstSpan">First span text</span>
    <span id="secondSpan">Second span text</span>
</li>

Я пытаюсь использовать .text(), чтобы получить только строку «Это какой-то текст», но если бы я сказал $('#list-item').text(),Я получаю «Это некоторый текст textFirst span textSecond span text».

Есть ли способ получить (и, возможно, удалить, например, .text("")) только свободный текст внутри тега, а не текст внутриего дочерние теги?

HTML не был написан мной, поэтому я должен работать с этим.Я знаю, что было бы просто обернуть текст в теги при написании HTML, но опять же, HTML уже написан заранее.

Ответы [ 23 ]

484 голосов
/ 13 января 2012

Мне понравилась эта многоразовая реализация, основанная на методе clone(), найденном здесь , чтобы получить только текст внутри родительского элемента.

Код для удобства использования:

$("#foo")
    .clone()    //clone the element
    .children() //select all the children
    .remove()   //remove all the children
    .end()  //again go back to selected element
    .text();
338 голосов
/ 07 февраля 2013

Простой ответ:

$("#listItem").contents().filter(function(){ 
  return this.nodeType == 3; 
})[0].nodeValue = "The text you want to replace with" 
130 голосов
/ 09 августа 2010

Это похоже на случай чрезмерного использования jquery для меня. Следующее будет захватывать текст, игнорируя другие узлы:

document.getElementById("listItem").childNodes[0];

Вам нужно будет обрезать это, но это даст вам то, что вы хотите в одной простой линии.

EDIT

Выше будет получен текстовый узел . Чтобы получить фактический текст, используйте это:

document.getElementById("listItem").childNodes[0].nodeValue;
58 голосов
/ 01 марта 2014

Проще и быстрее:

$("#listItem").contents().get(0).nodeValue
26 голосов
/ 23 августа 2015

Аналогично принятому ответу, но без клонирования:

$("#foo").contents().not($("#foo").children()).text();

И вот для этого есть плагин jQuery:

$.fn.immediateText = function() {
    return this.contents().not(this.children()).text();
};

Вот как использовать этот плагин:

$("#foo").immediateText(); // get the text without children
8 голосов
/ 05 января 2015

Попробуйте это:

$('#listItem').not($('#listItem').children()).text()
7 голосов
/ 30 августа 2012

это не код:

var text  =  $('#listItem').clone().children().remove().end().text();

просто становиться jQuery ради jQuery? Когда простые операции включают в себя столько цепочек команд и столько (ненужной) обработки, возможно, пришло время написать расширение jQuery:

(function ($) {
    function elementText(el, separator) {
        var textContents = [];
        for(var chld = el.firstChild; chld; chld = chld.nextSibling) {
            if (chld.nodeType == 3) { 
                textContents.push(chld.nodeValue);
            }
        }
        return textContents.join(separator);
    }
    $.fn.textNotChild = function(elementSeparator, nodeSeparator) {
    if (arguments.length<2){nodeSeparator="";}
    if (arguments.length<1){elementSeparator="";}
        return $.map(this, function(el){
            return elementText(el,nodeSeparator);
        }).join(elementSeparator);
    }
} (jQuery));

позвонить:

var text = $('#listItem').textNotChild();

аргументы в случае, если встречается другой сценарий, такой как

<li>some text<a>more text</a>again more</li>
<li>second text<a>more text</a>again more</li>

var text = $("li").textNotChild(".....","<break>");

текст будет иметь значение:

some text<break>again more.....second text<break>again more
6 голосов
/ 09 августа 2010

Это должно быть что-то с учетом потребностей, которые зависят от структуры, с которой вы представлены.Для приведенного вами примера это работает:

$(document).ready(function(){
     var $tmp = $('#listItem').children().remove();
     $('#listItem').text('').append($tmp);
});

Демонстрация: http://jquery.nodnod.net/cases/2385/run

Но это в значительной степени зависит от разметки, похожей на ту, которую вы опубликовали.

4 голосов
/ 01 сентября 2015
$($('#listItem').contents()[0]).text()

Краткий вариант Ответ Стюарта.

или с get()

$($('#listItem').contents().get(0)).text()
3 голосов
/ 16 августа 2017
jQuery.fn.ownText = function () {
    return $(this).contents().filter(function () {
        return this.nodeType === Node.TEXT_NODE;
    }).text();
};
...