Использование .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 ]

2 голосов
/ 02 августа 2016

Полагаю, это также будет хорошим решением - если вы хотите получить содержимое всех текстовых узлов, которые являются прямыми потомками выбранного элемента.

$(selector).contents().filter(function(){ return this.nodeType == 3; }).text();

Примечание: документация jQuery использует аналогичный код для объяснения функции содержимого: https://api.jquery.com/contents/

P.S. Есть также немного более уродливый способ сделать это, но это показывает более подробно, как все работает, и позволяет использовать собственный разделитель между текстовыми узлами (возможно, вы хотите, чтобы там был разрыв строки)

$(selector).contents().filter(function(){ return this.nodeType == 3; }).map(function() { return this.nodeValue; }).toArray().join("");
2 голосов
/ 23 июля 2015

Это старый вопрос, но главный ответ очень неэффективен. Вот лучшее решение:

$.fn.myText = function() {
    var str = '';

    this.contents().each(function() {
        if (this.nodeType == 3) {
            str += this.textContent || this.innerText || '';
        }
    });

    return str;
};

И просто сделайте это:

$("#foo").myText();
1 голос
/ 17 января 2019

Если позиция index текстового узла фиксирована среди его родных братьев, вы можете использовать

$('parentselector').contents().eq(index).text()
0 голосов
/ 17 марта 2016

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

function textNodesOnlyUnder(el) {
  var resultSet = [];
  var n = null;
  var treeWalker  = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, function (node) {
    if (node.parentNode.id == el.id && node.textContent.trim().length != 0) {
      return NodeFilter.FILTER_ACCEPT;
    }
    return NodeFilter.FILTER_SKIP;
  }, false);
  while (n = treeWalker.nextNode()) {
    resultSet.push(n);
  }
  return resultSet;
}



window.onload = function() {
  var ele = document.getElementById('listItem');
  var textNodesOnly = textNodesOnlyUnder(ele);
  var resultingText = textNodesOnly.map(function(val, index, arr) {
    return 'Text element N. ' + index + ' --> ' + val.textContent.trim();
  }).join('\n');
  document.getElementById('txtArea').value = resultingText;
}
<li id="listItem">
    This is some text
    <span id="firstSpan">First span text</span>
    <span id="secondSpan">Second span text</span>
</li>
<textarea id="txtArea" style="width: 400px;height: 200px;"></textarea>
0 голосов
/ 17 марта 2016

Я не эксперт по jquery, но как насчет

$('#listItem').children().first().text()
0 голосов
/ 09 августа 2010

Это не проверено, но я думаю, что вы можете попробовать что-то вроде этого:

 $('#listItem').not('span').text();

http://api.jquery.com/not/

0 голосов
/ 10 февраля 2012

Это хороший способ для меня

   var text  =  $('#listItem').clone().children().remove().end().text();
0 голосов
/ 11 апреля 2013

Используйте дополнительное условие, чтобы проверить, совпадают ли innerHTML и innerText.Только в этих случаях замените текст.

$(function() {
$('body *').each(function () {
    console.log($(this).html());
    console.log($(this).text());
    if($(this).text() === "Search" && $(this).html()===$(this).text())  {
        $(this).html("Find");
    }
})
})

http://jsfiddle.net/7RSGh/

0 голосов
/ 02 октября 2014

Чтобы иметь возможность обрезать результат, используйте DotNetWala, например, так:

$("#foo")
    .clone()    //clone the element
    .children() //select all the children
    .remove()   //remove all the children
    .end()  //again go back to selected element
    .text()
    .trim();

Я обнаружил, что использование более короткой версии, такой как document.getElementById("listItem").childNodes[0], не будет работать с trim () в jQuery.

0 голосов
/ 20 августа 2013

Вы можете попробовать это

alert(document.getElementById('listItem').firstChild.data)
...