Используя jQuery для сбора всех текстовых узлов от перенесенного набора, разделенного пробелами

Я ищу способ заключить, что весь текст в jQuery перенес набор, но я должен создать пространства между одноуровневыми узлами, которые не имеют никаких текстовых узлов между ними.

Например, рассмотрите этот HTML:

<div>
  <ul>
    <li>List item #1.</li><li>List item #2.</li><li>List item #3.</li>
  </ul>
</div>

Если я просто использую jQuery text() метод для сбора текстового содержания <div>, как такой:

var $div = $('div'), text = $div.text().trim();

alert(text);

это производит следующий текст:

Элемент списка № 1. Элемент списка № 2. Элемент списка № 3.

потому что нет никакого пробела между каждым <li> элемент. То, что я на самом деле ищу, является этим (отметьте одиночный пробел между каждым предложением):

Элемент списка № 1. Элемент списка № 3. Элемент списка № 3.

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

var $div = $('div'), text = '';

$div.find('*').each(function() {
  text += $(this).text().trim() + ' ';
});

alert(text);

но это произвело следующий текст:

Это - элемент списка № 1. Это - элемент списка № 2. Это - элемент списка № 3. Это - элемент списка № 1. Это - элемент списка № 2. Это - элемент списка № 3.

Я предполагаю, что это вызвано тем, что я выполняю итерации через каждого потомка <div> и добавление текста, таким образом, я получаю текстовые узлы в обоих <ul> и каждый из <li> дети, ведя к дублированному тексту.

Я думаю, что мог, вероятно, находить/писать плоскость функцией JavaScript для рекурсивного обхода DOM перенесенного набора, собираясь и добавляя текстовые узлы - но являюсь там более простым способом сделать это использование jQuery? Непротиворечивость перекрестного браузера очень важна.

Спасибо за любую справку!

9
задан Bungle 14 May 2010 в 17:40
поделиться

2 ответа

jQuery работает в основном с элементами, его возможности по работе с текстовыми узлами относительно слабы. Вы можете получить список всех дочерних элементов с помощью contents(), но вам все равно придется пройтись по нему, проверяя типы, так что это ничем не отличается от использования обычного DOM childNodes. Не существует метода рекурсивного получения текстовых узлов, поэтому вам придется написать что-то самостоятельно, например, что-то вроде:

function collectTextNodes(element, texts) {
    for (var child= element.firstChild; child!==null; child= child.nextSibling) {
        if (child.nodeType===3)
            texts.push(child);
        else if (child.nodeType===1)
            collectTextNodes(child, texts);
    }
}
function getTextWithSpaces(element) {
    var texts= [];
    collectTextNodes(element, texts);
    for (var i= texts.length; i-->0;)
        texts[i]= texts[i].data;
    return texts.join(' ');
}
7
ответ дан 4 December 2019 в 21:48
поделиться

Вы можете использовать метод jQuery contents () , чтобы получить все узлы (включая текстовые узлы), а затем отфильтровать свой набор только до текстовых узлов.

$("body").find("*").contents().filter(function(){return this.nodeType!==1;});

Оттуда вы можете создать любую структуру, которая вам нужна.

0
ответ дан 4 December 2019 в 21:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: